All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] ss: Get netlink sockets info via sock-diag (v2)
@ 2013-06-05  8:41 Andrey Vagin
  2013-06-05  8:41 ` [PATCH 1/4] ss: handle socket diag request in a separate function Andrey Vagin
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Andrey Vagin @ 2013-06-05  8:41 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Andrey Vagin

On Thu, Mar 21, 2013 at 10:00:25AM -0700, Stephen Hemminger wrote:
> Since this depends on functionality not in the upstream kernel.
> Resubmit this during the 3.10 merge window. At the start of the merge
> window, headers are synchronized with the kernel headers.

Netlink socket diag is in the upstream kernel since 3.10-rc1.

v2: Update kernel headers

Andrey Vagin (4):
  ss: handle socket diag request in a separate function
  ss: create a function to print info about netlink sockets
  ss: show destination address for netlink sockets
  ss: Get netlink sockets info via sock-diag (v2)

 include/linux/netlink_diag.h |  52 ++++++++++
 misc/ss.c                    | 242 +++++++++++++++++++++++++++++--------------
 2 files changed, 216 insertions(+), 78 deletions(-)
 create mode 100644 include/linux/netlink_diag.h

-- 
1.8.2

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

* [PATCH 1/4] ss: handle socket diag request in a separate function
  2013-06-05  8:41 [PATCH 0/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
@ 2013-06-05  8:41 ` Andrey Vagin
  2013-06-05  8:41 ` [PATCH 2/4] ss: create a function to print info about netlink sockets Andrey Vagin
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrey Vagin @ 2013-06-05  8:41 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Andrey Vagin

It will be reused to show netlink sockets

Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Andrey Vagin <avagin@openvz.org>
---
 misc/ss.c | 49 +++++++++++++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 418dd6f..2d6ddef 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -2226,31 +2226,17 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
 	return 0;
 }
 
-static int unix_show_netlink(struct filter *f, FILE *dump_fp)
+static int handle_netlink_request(struct filter *f, FILE *dump_fp,
+				  struct nlmsghdr *req, size_t size,
+				  int (* show_one_sock)(struct nlmsghdr *nlh, struct filter *f))
 {
 	int fd;
-	struct {
-		struct nlmsghdr nlh;
-		struct unix_diag_req r;
-	} req;
 	char	buf[8192];
 
 	if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG)) < 0)
 		return -1;
 
-	memset(&req, 0, sizeof(req));
-	req.nlh.nlmsg_len = sizeof(req);
-	req.nlh.nlmsg_type = SOCK_DIAG_BY_FAMILY;
-	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
-	req.nlh.nlmsg_seq = 123456;
-
-	req.r.sdiag_family = AF_UNIX;
-	req.r.udiag_states = f->states;
-	req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN;
-	if (show_mem)
-		req.r.udiag_show |= UDIAG_SHOW_MEMINFO;
-
-	if (send(fd, &req, sizeof(req), 0) < 0) {
+	if (send(fd, req, size, 0) < 0) {
 		close(fd);
 		return -1;
 	}
@@ -2295,13 +2281,13 @@ static int unix_show_netlink(struct filter *f, FILE *dump_fp)
 				} else {
 					errno = -err->error;
 					if (errno != ENOENT)
-						fprintf(stderr, "UDIAG answers %d\n", errno);
+						fprintf(stderr, "DIAG answers %d\n", errno);
 				}
 				close(fd);
 				return -1;
 			}
 			if (!dump_fp) {
-				err = unix_show_sock(h, f);
+				err = show_one_sock(h, f);
 				if (err < 0) {
 					close(fd);
 					return err;
@@ -2323,6 +2309,29 @@ close_it:
 	return 0;
 }
 
+static int unix_show_netlink(struct filter *f, FILE *dump_fp)
+{
+	struct {
+		struct nlmsghdr nlh;
+		struct unix_diag_req r;
+	} req;
+
+	memset(&req, 0, sizeof(req));
+	req.nlh.nlmsg_len = sizeof(req);
+	req.nlh.nlmsg_type = SOCK_DIAG_BY_FAMILY;
+	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
+	req.nlh.nlmsg_seq = 123456;
+
+	req.r.sdiag_family = AF_UNIX;
+	req.r.udiag_states = f->states;
+	req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN;
+	if (show_mem)
+		req.r.udiag_show |= UDIAG_SHOW_MEMINFO;
+
+	return handle_netlink_request(f, dump_fp, &req.nlh,
+					sizeof(req), unix_show_sock);
+}
+
 static int unix_show(struct filter *f)
 {
 	FILE *fp;
-- 
1.8.1.4

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

* [PATCH 2/4] ss: create a function to print info about netlink sockets
  2013-06-05  8:41 [PATCH 0/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
  2013-06-05  8:41 ` [PATCH 1/4] ss: handle socket diag request in a separate function Andrey Vagin
@ 2013-06-05  8:41 ` Andrey Vagin
  2013-06-05  8:42 ` [PATCH 3/4] ss: show destination address for " Andrey Vagin
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrey Vagin @ 2013-06-05  8:41 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Andrey Vagin

It will be reused for printing info about netlink sockets, when
socket diag is used for retrieving information.

Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Andrey Vagin <avagin@openvz.org>
---
 misc/ss.c | 130 ++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 72 insertions(+), 58 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 2d6ddef..469ffd0 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -2672,6 +2672,73 @@ static int packet_show(struct filter *f)
 	return 0;
 }
 
+static void netlink_show_one(struct filter *f,
+				int prot, int pid, unsigned groups,
+				int rq, int wq,
+				unsigned long long sk, unsigned long long cb)
+{
+	if (f->f) {
+		struct tcpstat tst;
+		tst.local.family = AF_NETLINK;
+		tst.remote.family = AF_NETLINK;
+		tst.rport = -1;
+		tst.lport = pid;
+		tst.local.data[0] = prot;
+		tst.remote.data[0] = 0;
+		if (run_ssfilter(f->f, &tst) == 0)
+			return;
+	}
+
+	if (netid_width)
+		printf("%-*s ", netid_width, "nl");
+	if (state_width)
+		printf("%-*s ", state_width, "UNCONN");
+	printf("%-6d %-6d ", rq, wq);
+	if (resolve_services && prot == 0)
+		printf("%*s:", addr_width, "rtnl");
+	else if (resolve_services && prot == 3)
+		printf("%*s:", addr_width, "fw");
+	else if (resolve_services && prot == 4)
+		printf("%*s:", addr_width, "tcpdiag");
+	else
+		printf("%*d:", addr_width, prot);
+	if (pid == -1) {
+		printf("%-*s ", serv_width, "*");
+	} else if (resolve_services) {
+		int done = 0;
+		if (!pid) {
+			done = 1;
+			printf("%-*s ", serv_width, "kernel");
+		} else if (pid > 0) {
+			char procname[64];
+			FILE *fp;
+			sprintf(procname, "%s/%d/stat",
+				getenv("PROC_ROOT") ? : "/proc", pid);
+			if ((fp = fopen(procname, "r")) != NULL) {
+				if (fscanf(fp, "%*d (%[^)])", procname) == 1) {
+					sprintf(procname+strlen(procname), "/%d", pid);
+					printf("%-*s ", serv_width, procname);
+					done = 1;
+				}
+				fclose(fp);
+			}
+		}
+		if (!done)
+			printf("%-*d ", serv_width, pid);
+	} else {
+		printf("%-*d ", serv_width, pid);
+	}
+	printf("%*s*%-*s",
+	       addr_width, "", serv_width, "");
+
+	if (show_details) {
+		printf(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups);
+	}
+	printf("\n");
+
+	return;
+}
+
 static int netlink_show(struct filter *f)
 {
 	FILE *fp;
@@ -2684,6 +2751,10 @@ static int netlink_show(struct filter *f)
 	if (!(f->states & (1<<SS_CLOSE)))
 		return 0;
 
+	if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") &&
+		netlink_show_netlink(f, NULL) == 0)
+		return 0;
+
 	if ((fp = net_netlink_open()) == NULL)
 		return -1;
 	fgets(buf, sizeof(buf)-1, fp);
@@ -2693,64 +2764,7 @@ static int netlink_show(struct filter *f)
 		       &sk,
 		       &prot, &pid, &groups, &rq, &wq, &cb, &rc);
 
-		if (f->f) {
-			struct tcpstat tst;
-			tst.local.family = AF_NETLINK;
-			tst.remote.family = AF_NETLINK;
-			tst.rport = -1;
-			tst.lport = pid;
-			tst.local.data[0] = prot;
-			tst.remote.data[0] = 0;
-			if (run_ssfilter(f->f, &tst) == 0)
-				continue;
-		}
-
-		if (netid_width)
-			printf("%-*s ", netid_width, "nl");
-		if (state_width)
-			printf("%-*s ", state_width, "UNCONN");
-		printf("%-6d %-6d ", rq, wq);
-		if (resolve_services && prot == 0)
-			printf("%*s:", addr_width, "rtnl");
-		else if (resolve_services && prot == 3)
-			printf("%*s:", addr_width, "fw");
-		else if (resolve_services && prot == 4)
-			printf("%*s:", addr_width, "tcpdiag");
-		else
-			printf("%*d:", addr_width, prot);
-		if (pid == -1) {
-			printf("%-*s ", serv_width, "*");
-		} else if (resolve_services) {
-			int done = 0;
-			if (!pid) {
-				done = 1;
-				printf("%-*s ", serv_width, "kernel");
-			} else if (pid > 0) {
-				char procname[64];
-				FILE *fp;
-				sprintf(procname, "%s/%d/stat",
-					getenv("PROC_ROOT") ? : "/proc", pid);
-				if ((fp = fopen(procname, "r")) != NULL) {
-					if (fscanf(fp, "%*d (%[^)])", procname) == 1) {
-						sprintf(procname+strlen(procname), "/%d", pid);
-						printf("%-*s ", serv_width, procname);
-						done = 1;
-					}
-					fclose(fp);
-				}
-			}
-			if (!done)
-				printf("%-*d ", serv_width, pid);
-		} else {
-			printf("%-*d ", serv_width, pid);
-		}
-		printf("%*s*%-*s",
-		       addr_width, "", serv_width, "");
-
-		if (show_details) {
-			printf(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups);
-		}
-		printf("\n");
+		netlink_show_one(f, prot, pid, groups, rq, wq, sk, cb);
 	}
 
 	return 0;
-- 
1.8.1.4

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

* [PATCH 3/4] ss: show destination address for netlink sockets
  2013-06-05  8:41 [PATCH 0/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
  2013-06-05  8:41 ` [PATCH 1/4] ss: handle socket diag request in a separate function Andrey Vagin
  2013-06-05  8:41 ` [PATCH 2/4] ss: create a function to print info about netlink sockets Andrey Vagin
@ 2013-06-05  8:42 ` Andrey Vagin
  2013-06-05  8:42 ` [PATCH 4/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
  2013-06-05 15:56 ` [PATCH 0/4] " Stephen Hemminger
  4 siblings, 0 replies; 6+ messages in thread
From: Andrey Vagin @ 2013-06-05  8:42 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Andrey Vagin

A netlink socket may be connected to a specific group.

Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Andrey Vagin <avagin@openvz.org>
---
 misc/ss.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 469ffd0..c8534ff 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -2674,6 +2674,7 @@ static int packet_show(struct filter *f)
 
 static void netlink_show_one(struct filter *f,
 				int prot, int pid, unsigned groups,
+				int state, int dst_pid, unsigned dst_group,
 				int rq, int wq,
 				unsigned long long sk, unsigned long long cb)
 {
@@ -2728,8 +2729,14 @@ static void netlink_show_one(struct filter *f,
 	} else {
 		printf("%-*d ", serv_width, pid);
 	}
-	printf("%*s*%-*s",
-	       addr_width, "", serv_width, "");
+
+	if (state == NETLINK_CONNECTED) {
+		printf("%*d:%-*d",
+		       addr_width, dst_group, serv_width, dst_pid);
+	} else {
+		printf("%*s*%-*s",
+		       addr_width, "", serv_width, "");
+	}
 
 	if (show_details) {
 		printf(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups);
@@ -2764,7 +2771,7 @@ static int netlink_show(struct filter *f)
 		       &sk,
 		       &prot, &pid, &groups, &rq, &wq, &cb, &rc);
 
-		netlink_show_one(f, prot, pid, groups, rq, wq, sk, cb);
+		netlink_show_one(f, prot, pid, groups, 0, 0, 0, rq, wq, sk, cb);
 	}
 
 	return 0;
-- 
1.8.1.4

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

* [PATCH 4/4] ss: Get netlink sockets info via sock-diag (v2)
  2013-06-05  8:41 [PATCH 0/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
                   ` (2 preceding siblings ...)
  2013-06-05  8:42 ` [PATCH 3/4] ss: show destination address for " Andrey Vagin
@ 2013-06-05  8:42 ` Andrey Vagin
  2013-06-05 15:56 ` [PATCH 0/4] " Stephen Hemminger
  4 siblings, 0 replies; 6+ messages in thread
From: Andrey Vagin @ 2013-06-05  8:42 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Andrey Vagin

v2: update netlink_diag.h

Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Andrey Vagin <avagin@openvz.org>
---
 include/linux/netlink_diag.h | 52 ++++++++++++++++++++++++++++++++++++++++
 misc/ss.c                    | 56 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)
 create mode 100644 include/linux/netlink_diag.h

diff --git a/include/linux/netlink_diag.h b/include/linux/netlink_diag.h
new file mode 100644
index 0000000..4e31db4
--- /dev/null
+++ b/include/linux/netlink_diag.h
@@ -0,0 +1,52 @@
+#ifndef __NETLINK_DIAG_H__
+#define __NETLINK_DIAG_H__
+
+#include <linux/types.h>
+
+struct netlink_diag_req {
+	__u8	sdiag_family;
+	__u8	sdiag_protocol;
+	__u16	pad;
+	__u32	ndiag_ino;
+	__u32	ndiag_show;
+	__u32	ndiag_cookie[2];
+};
+
+struct netlink_diag_msg {
+	__u8	ndiag_family;
+	__u8	ndiag_type;
+	__u8	ndiag_protocol;
+	__u8	ndiag_state;
+
+	__u32	ndiag_portid;
+	__u32	ndiag_dst_portid;
+	__u32	ndiag_dst_group;
+	__u32	ndiag_ino;
+	__u32	ndiag_cookie[2];
+};
+
+struct netlink_diag_ring {
+	__u32	ndr_block_size;
+	__u32	ndr_block_nr;
+	__u32	ndr_frame_size;
+	__u32	ndr_frame_nr;
+};
+
+enum {
+	NETLINK_DIAG_MEMINFO,
+	NETLINK_DIAG_GROUPS,
+	NETLINK_DIAG_RX_RING,
+	NETLINK_DIAG_TX_RING,
+
+	__NETLINK_DIAG_MAX,
+};
+
+#define NETLINK_DIAG_MAX (__NETLINK_DIAG_MAX - 1)
+
+#define NDIAG_PROTO_ALL		((__u8) ~0)
+
+#define NDIAG_SHOW_MEMINFO	0x00000001 /* show memory info of a socket */
+#define NDIAG_SHOW_GROUPS	0x00000002 /* show groups of a netlink socket */
+#define NDIAG_SHOW_RING_CFG	0x00000004 /* show ring configuration */
+
+#endif
diff --git a/misc/ss.c b/misc/ss.c
index c8534ff..e0d11ff 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -39,6 +39,7 @@
 #include <linux/netdevice.h>	/* for MAX_ADDR_LEN */
 #include <linux/filter.h>
 #include <linux/packet_diag.h>
+#include <linux/netlink_diag.h>
 
 int resolve_hosts = 0;
 int resolve_services = 1;
@@ -2746,6 +2747,61 @@ static void netlink_show_one(struct filter *f,
 	return;
 }
 
+static int netlink_show_sock(struct nlmsghdr *nlh, struct filter *f)
+{
+	struct netlink_diag_msg *r = NLMSG_DATA(nlh);
+	struct rtattr *tb[NETLINK_DIAG_MAX+1];
+	int rq = 0, wq = 0;
+	unsigned long groups = 0;
+
+	parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr*)(r+1),
+		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
+
+	if (tb[NETLINK_DIAG_GROUPS] && RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS]))
+		groups = *(unsigned long *) RTA_DATA(tb[NETLINK_DIAG_GROUPS]);
+
+	if (tb[NETLINK_DIAG_MEMINFO]) {
+		const __u32 *skmeminfo;
+		skmeminfo = RTA_DATA(tb[NETLINK_DIAG_MEMINFO]);
+
+		rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
+		wq = skmeminfo[SK_MEMINFO_WMEM_ALLOC];
+	}
+
+	netlink_show_one(f, r->ndiag_protocol, r->ndiag_portid, groups,
+			 r->ndiag_state, r->ndiag_dst_portid, r->ndiag_dst_group,
+			 rq, wq, 0, 0);
+
+	if (show_mem) {
+		printf("\t");
+		print_skmeminfo(tb, NETLINK_DIAG_MEMINFO);
+		printf("\n");
+	}
+
+	return 0;
+}
+
+static int netlink_show_netlink(struct filter *f, FILE *dump_fp)
+{
+	struct {
+		struct nlmsghdr nlh;
+		struct netlink_diag_req r;
+	} req;
+
+	memset(&req, 0, sizeof(req));
+	req.nlh.nlmsg_len = sizeof(req);
+	req.nlh.nlmsg_type = SOCK_DIAG_BY_FAMILY;
+	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
+	req.nlh.nlmsg_seq = 123456;
+
+	req.r.sdiag_family = AF_NETLINK;
+	req.r.sdiag_protocol = NDIAG_PROTO_ALL;
+	req.r.ndiag_show = NDIAG_SHOW_GROUPS | NDIAG_SHOW_MEMINFO;
+
+	return handle_netlink_request(f, dump_fp, &req.nlh,
+					sizeof(req), netlink_show_sock);
+}
+
 static int netlink_show(struct filter *f)
 {
 	FILE *fp;
-- 
1.8.1.4

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

* Re: [PATCH 0/4] ss: Get netlink sockets info via sock-diag (v2)
  2013-06-05  8:41 [PATCH 0/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
                   ` (3 preceding siblings ...)
  2013-06-05  8:42 ` [PATCH 4/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
@ 2013-06-05 15:56 ` Stephen Hemminger
  4 siblings, 0 replies; 6+ messages in thread
From: Stephen Hemminger @ 2013-06-05 15:56 UTC (permalink / raw)
  To: Andrey Vagin; +Cc: netdev

On Wed,  5 Jun 2013 12:41:57 +0400
Andrey Vagin <avagin@openvz.org> wrote:

> On Thu, Mar 21, 2013 at 10:00:25AM -0700, Stephen Hemminger wrote:
> > Since this depends on functionality not in the upstream kernel.
> > Resubmit this during the 3.10 merge window. At the start of the merge
> > window, headers are synchronized with the kernel headers.
> 
> Netlink socket diag is in the upstream kernel since 3.10-rc1.
> 
> v2: Update kernel headers
> 
> Andrey Vagin (4):
>   ss: handle socket diag request in a separate function
>   ss: create a function to print info about netlink sockets
>   ss: show destination address for netlink sockets
>   ss: Get netlink sockets info via sock-diag (v2)
> 
>  include/linux/netlink_diag.h |  52 ++++++++++
>  misc/ss.c                    | 242 +++++++++++++++++++++++++++++--------------
>  2 files changed, 216 insertions(+), 78 deletions(-)
>  create mode 100644 include/linux/netlink_diag.h
> 


Applied

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

end of thread, other threads:[~2013-06-05 15:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-05  8:41 [PATCH 0/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
2013-06-05  8:41 ` [PATCH 1/4] ss: handle socket diag request in a separate function Andrey Vagin
2013-06-05  8:41 ` [PATCH 2/4] ss: create a function to print info about netlink sockets Andrey Vagin
2013-06-05  8:42 ` [PATCH 3/4] ss: show destination address for " Andrey Vagin
2013-06-05  8:42 ` [PATCH 4/4] ss: Get netlink sockets info via sock-diag (v2) Andrey Vagin
2013-06-05 15:56 ` [PATCH 0/4] " Stephen Hemminger

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.