All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 iproute2 0/3] ss: Add support to filter by device
@ 2016-06-27 18:34 David Ahern
  2016-06-27 18:34 ` [PATCH v2 iproute2 1/3] ss: Refactor inet_show_sock David Ahern
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: David Ahern @ 2016-06-27 18:34 UTC (permalink / raw)
  To: netdev; +Cc: stephen, David Ahern

Add support for specifying device name in the filter to ss.
The kernel does not provide support for iface filtering, so if
the user specifies 'dev == NAME' or 'dev != NAME' all filtering
is done in userspace.

I will send a patch to add support for iface filtering in the kernel,
but the reality is that ss will need to accommodate both (ie., lack of
kernel support) for some time - which this set provides.

v2
- fixed checkpatch errors and warnings

David Ahern (3):
  ss: Refactor inet_show_sock
  ss: Allow ssfilter_bytecompile to return 0
  ss: Add support to filter on device

 misc/ss.c       | 159 +++++++++++++++++++++++++++++++++++++++++---------------
 misc/ssfilter.h |   2 +
 misc/ssfilter.y |  22 +++++++-
 3 files changed, 140 insertions(+), 43 deletions(-)

-- 
2.1.4

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

* [PATCH v2 iproute2 1/3] ss: Refactor inet_show_sock
  2016-06-27 18:34 [PATCH v2 iproute2 0/3] ss: Add support to filter by device David Ahern
@ 2016-06-27 18:34 ` David Ahern
  2016-06-27 18:34 ` [PATCH v2 iproute2 2/3] ss: Allow ssfilter_bytecompile to return 0 David Ahern
  2016-06-27 18:34 ` [PATCH v2 iproute2 3/3] ss: Add support to filter on device David Ahern
  2 siblings, 0 replies; 7+ messages in thread
From: David Ahern @ 2016-06-27 18:34 UTC (permalink / raw)
  To: netdev; +Cc: stephen, David Ahern

Extract parsing of sockstat and filter from inet_show_sock.
While moving run_ssfilter into callers of inet_show_sock enable
userspace filtering before the kill.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 misc/ss.c | 75 ++++++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 48 insertions(+), 27 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 02be7e7407df..f164ca920308 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -2038,42 +2038,48 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
 	}
 }
 
-static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
+static void parse_diag_msg(struct nlmsghdr *nlh, struct sockstat *s)
 {
 	struct rtattr *tb[INET_DIAG_MAX+1];
 	struct inet_diag_msg *r = NLMSG_DATA(nlh);
-	struct sockstat s = {};
 
 	parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr *)(r+1),
 		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
-	s.state		= r->idiag_state;
-	s.local.family  = s.remote.family = r->idiag_family;
-	s.lport		= ntohs(r->id.idiag_sport);
-	s.rport		= ntohs(r->id.idiag_dport);
-	s.wq		= r->idiag_wqueue;
-	s.rq		= r->idiag_rqueue;
-	s.ino		= r->idiag_inode;
-	s.uid		= r->idiag_uid;
-	s.iface		= r->id.idiag_if;
-	s.sk		= cookie_sk_get(&r->id.idiag_cookie[0]);
-
-	if (s.local.family == AF_INET) {
-		s.local.bytelen = s.remote.bytelen = 4;
-	} else {
-		s.local.bytelen = s.remote.bytelen = 16;
-	}
+	s->state	= r->idiag_state;
+	s->local.family	= s->remote.family = r->idiag_family;
+	s->lport	= ntohs(r->id.idiag_sport);
+	s->rport	= ntohs(r->id.idiag_dport);
+	s->wq		= r->idiag_wqueue;
+	s->rq		= r->idiag_rqueue;
+	s->ino		= r->idiag_inode;
+	s->uid		= r->idiag_uid;
+	s->iface	= r->id.idiag_if;
+	s->sk		= cookie_sk_get(&r->id.idiag_cookie[0]);
+
+	if (s->local.family == AF_INET)
+		s->local.bytelen = s->remote.bytelen = 4;
+	else
+		s->local.bytelen = s->remote.bytelen = 16;
 
-	memcpy(s.local.data, r->id.idiag_src, s.local.bytelen);
-	memcpy(s.remote.data, r->id.idiag_dst, s.local.bytelen);
+	memcpy(s->local.data, r->id.idiag_src, s->local.bytelen);
+	memcpy(s->remote.data, r->id.idiag_dst, s->local.bytelen);
+}
 
-	if (f && f->f && run_ssfilter(f->f, &s) == 0)
-		return 0;
+static int inet_show_sock(struct nlmsghdr *nlh,
+			  struct sockstat *s,
+			  int protocol)
+{
+	struct rtattr *tb[INET_DIAG_MAX+1];
+	struct inet_diag_msg *r = NLMSG_DATA(nlh);
+
+	parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr *)(r+1),
+		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
 	if (tb[INET_DIAG_PROTOCOL])
 		protocol = *(__u8 *)RTA_DATA(tb[INET_DIAG_PROTOCOL]);
 
-	inet_stats_print(&s, protocol);
+	inet_stats_print(s, protocol);
 
 	if (show_options) {
 		struct tcpstat t = {};
@@ -2085,8 +2091,8 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
 	}
 
 	if (show_details) {
-		sock_details_print(&s);
-		if (s.local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY]) {
+		sock_details_print(s);
+		if (s->local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY]) {
 			unsigned char v6only;
 
 			v6only = *(__u8 *)RTA_DATA(tb[INET_DIAG_SKV6ONLY]);
@@ -2268,9 +2274,16 @@ static int show_one_inet_sock(const struct sockaddr_nl *addr,
 	int err;
 	struct inet_diag_arg *diag_arg = arg;
 	struct inet_diag_msg *r = NLMSG_DATA(h);
+	struct sockstat s = {};
 
 	if (!(diag_arg->f->families & (1 << r->idiag_family)))
 		return 0;
+
+	parse_diag_msg(h, &s);
+
+	if (diag_arg->f->f && run_ssfilter(diag_arg->f->f, &s) == 0)
+		return 0;
+
 	if (diag_arg->f->kill && kill_inet_sock(h, arg) != 0) {
 		if (errno == EOPNOTSUPP || errno == ENOENT) {
 			/* Socket can't be closed, or is already closed. */
@@ -2280,7 +2293,9 @@ static int show_one_inet_sock(const struct sockaddr_nl *addr,
 			return -1;
 		}
 	}
-	if ((err = inet_show_sock(h, diag_arg->f, diag_arg->protocol)) < 0)
+
+	err = inet_show_sock(h, &s, diag_arg->protocol);
+	if (err < 0)
 		return err;
 
 	return 0;
@@ -2345,6 +2360,7 @@ static int tcp_show_netlink_file(struct filter *f)
 	while (1) {
 		int status, err;
 		struct nlmsghdr *h = (struct nlmsghdr *)buf;
+		struct sockstat s = {};
 
 		status = fread(buf, 1, sizeof(*h), fp);
 		if (status < 0) {
@@ -2383,7 +2399,12 @@ static int tcp_show_netlink_file(struct filter *f)
 			return -1;
 		}
 
-		err = inet_show_sock(h, f, IPPROTO_TCP);
+		parse_diag_msg(h, &s);
+
+		if (f && f->f && run_ssfilter(f->f, &s) == 0)
+			continue;
+
+		err = inet_show_sock(h, &s, IPPROTO_TCP);
 		if (err < 0)
 			return err;
 	}
-- 
2.1.4

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

* [PATCH v2 iproute2 2/3] ss: Allow ssfilter_bytecompile to return 0
  2016-06-27 18:34 [PATCH v2 iproute2 0/3] ss: Add support to filter by device David Ahern
  2016-06-27 18:34 ` [PATCH v2 iproute2 1/3] ss: Refactor inet_show_sock David Ahern
@ 2016-06-27 18:34 ` David Ahern
  2016-06-27 18:34 ` [PATCH v2 iproute2 3/3] ss: Add support to filter on device David Ahern
  2 siblings, 0 replies; 7+ messages in thread
From: David Ahern @ 2016-06-27 18:34 UTC (permalink / raw)
  To: netdev; +Cc: stephen, David Ahern

Allow ssfilter_bytecompile to return 0 for filter ops the kernel
does not support. If such an op is in the filter string then all
filtering is done in userspace.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 misc/ss.c | 52 +++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index f164ca920308..0510701619ac 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -1273,11 +1273,16 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
 
 		case SSF_AND:
 	{
-		char *a1, *a2, *a;
+		char *a1 = NULL, *a2 = NULL, *a;
 		int l1, l2;
 
 		l1 = ssfilter_bytecompile(f->pred, &a1);
 		l2 = ssfilter_bytecompile(f->post, &a2);
+		if (!l1 || !l2) {
+			free(a1);
+			free(a2);
+			return 0;
+		}
 		if (!(a = malloc(l1+l2))) abort();
 		memcpy(a, a1, l1);
 		memcpy(a+l1, a2, l2);
@@ -1288,11 +1293,16 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
 	}
 		case SSF_OR:
 	{
-		char *a1, *a2, *a;
+		char *a1 = NULL, *a2 = NULL, *a;
 		int l1, l2;
 
 		l1 = ssfilter_bytecompile(f->pred, &a1);
 		l2 = ssfilter_bytecompile(f->post, &a2);
+		if (!l1 || !l2) {
+			free(a1);
+			free(a2);
+			return 0;
+		}
 		if (!(a = malloc(l1+l2+4))) abort();
 		memcpy(a, a1, l1);
 		memcpy(a+l1+4, a2, l2);
@@ -1303,10 +1313,14 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
 	}
 		case SSF_NOT:
 	{
-		char *a1, *a;
+		char *a1 = NULL, *a;
 		int l1;
 
 		l1 = ssfilter_bytecompile(f->pred, &a1);
+		if (!l1) {
+			free(a1);
+			return 0;
+		}
 		if (!(a = malloc(l1+4))) abort();
 		memcpy(a, a1, l1);
 		free(a1);
@@ -2127,6 +2141,7 @@ static int tcpdiag_send(int fd, int protocol, struct filter *f)
 	struct msghdr msg;
 	struct rtattr rta;
 	struct iovec iov[3];
+	int iovlen = 1;
 
 	if (protocol == IPPROTO_UDP)
 		return -1;
@@ -2162,18 +2177,21 @@ static int tcpdiag_send(int fd, int protocol, struct filter *f)
 	};
 	if (f->f) {
 		bclen = ssfilter_bytecompile(f->f, &bc);
-		rta.rta_type = INET_DIAG_REQ_BYTECODE;
-		rta.rta_len = RTA_LENGTH(bclen);
-		iov[1] = (struct iovec){ &rta, sizeof(rta) };
-		iov[2] = (struct iovec){ bc, bclen };
-		req.nlh.nlmsg_len += RTA_LENGTH(bclen);
+		if (bclen) {
+			rta.rta_type = INET_DIAG_REQ_BYTECODE;
+			rta.rta_len = RTA_LENGTH(bclen);
+			iov[1] = (struct iovec){ &rta, sizeof(rta) };
+			iov[2] = (struct iovec){ bc, bclen };
+			req.nlh.nlmsg_len += RTA_LENGTH(bclen);
+			iovlen = 3;
+		}
 	}
 
 	msg = (struct msghdr) {
 		.msg_name = (void *)&nladdr,
 		.msg_namelen = sizeof(nladdr),
 		.msg_iov = iov,
-		.msg_iovlen = f->f ? 3 : 1,
+		.msg_iovlen = iovlen,
 	};
 
 	if (sendmsg(fd, &msg, 0) < 0) {
@@ -2194,6 +2212,7 @@ static int sockdiag_send(int family, int fd, int protocol, struct filter *f)
 	struct msghdr msg;
 	struct rtattr rta;
 	struct iovec iov[3];
+	int iovlen = 1;
 
 	if (family == PF_UNSPEC)
 		return tcpdiag_send(fd, protocol, f);
@@ -2222,18 +2241,21 @@ static int sockdiag_send(int family, int fd, int protocol, struct filter *f)
 	};
 	if (f->f) {
 		bclen = ssfilter_bytecompile(f->f, &bc);
-		rta.rta_type = INET_DIAG_REQ_BYTECODE;
-		rta.rta_len = RTA_LENGTH(bclen);
-		iov[1] = (struct iovec){ &rta, sizeof(rta) };
-		iov[2] = (struct iovec){ bc, bclen };
-		req.nlh.nlmsg_len += RTA_LENGTH(bclen);
+		if (bclen) {
+			rta.rta_type = INET_DIAG_REQ_BYTECODE;
+			rta.rta_len = RTA_LENGTH(bclen);
+			iov[1] = (struct iovec){ &rta, sizeof(rta) };
+			iov[2] = (struct iovec){ bc, bclen };
+			req.nlh.nlmsg_len += RTA_LENGTH(bclen);
+			iovlen = 3;
+		}
 	}
 
 	msg = (struct msghdr) {
 		.msg_name = (void *)&nladdr,
 		.msg_namelen = sizeof(nladdr),
 		.msg_iov = iov,
-		.msg_iovlen = f->f ? 3 : 1,
+		.msg_iovlen = iovlen,
 	};
 
 	if (sendmsg(fd, &msg, 0) < 0) {
-- 
2.1.4

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

* [PATCH v2 iproute2 3/3] ss: Add support to filter on device
  2016-06-27 18:34 [PATCH v2 iproute2 0/3] ss: Add support to filter by device David Ahern
  2016-06-27 18:34 ` [PATCH v2 iproute2 1/3] ss: Refactor inet_show_sock David Ahern
  2016-06-27 18:34 ` [PATCH v2 iproute2 2/3] ss: Allow ssfilter_bytecompile to return 0 David Ahern
@ 2016-06-27 18:34 ` David Ahern
  2016-06-27 21:13   ` Stephen Hemminger
  2 siblings, 1 reply; 7+ messages in thread
From: David Ahern @ 2016-06-27 18:34 UTC (permalink / raw)
  To: netdev; +Cc: stephen, David Ahern

Add support for device names in the filter. Example:

    root@kenny:~# ss -t  'sport == :22 && dev == red'
    State      Recv-Q Send-Q     Local Address:Port      Peer Address:Port
    ESTAB      0      0          10.100.1.2%red:ssh      10.100.1.254:47814
    ESTAB      0      0           2100:1::2%red:ssh        2100:1::64:49406

Since kernel does not support iface in the filter specifying a
device name means all filtering is done in userspace.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 misc/ss.c       | 32 ++++++++++++++++++++++++++++++++
 misc/ssfilter.h |  2 ++
 misc/ssfilter.y | 22 +++++++++++++++++++++-
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/misc/ss.c b/misc/ss.c
index 0510701619ac..20ea3a44ffc5 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -1043,6 +1043,7 @@ static void inet_addr_print(const inet_prefix *a, int port, unsigned int ifindex
 struct aafilter {
 	inet_prefix	addr;
 	int		port;
+	unsigned int	iface;
 	struct aafilter *next;
 };
 
@@ -1157,7 +1158,12 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
 
 		return s->lport <= a->port;
 	}
+		case SSF_DEVCOND:
+	{
+		struct aafilter *a = (void *)f->pred;
 
+		return s->iface == a->iface;
+	}
 		/* Yup. It is recursion. Sorry. */
 		case SSF_AND:
 		return run_ssfilter(f->pred, s) && run_ssfilter(f->post, s);
@@ -1328,6 +1334,11 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
 		*bytecode = a;
 		return l1+4;
 	}
+		case SSF_DEVCOND:
+	{
+		/* bytecompile for SSF_DEVCOND not supported yet */
+		return 0;
+	}
 		default:
 		abort();
 	}
@@ -1416,6 +1427,27 @@ static int xll_name_to_index(const char *dev)
 	return ll_name_to_index(dev);
 }
 
+void *parse_devcond(char *name)
+{
+	struct aafilter a = { .iface = 0 };
+	struct aafilter *res;
+
+	a.iface = xll_name_to_index(name);
+	if (a.iface == 0) {
+		char *end;
+		unsigned long res;
+
+		res = strtoul(name, &end, 0);
+		if (!end || end == name || *end || res > UINT_MAX)
+			return NULL;
+	}
+
+	res = malloc(sizeof(*res));
+	*res = a;
+
+	return res;
+}
+
 void *parse_hostcond(char *addr, bool is_port)
 {
 	char *port = NULL;
diff --git a/misc/ssfilter.h b/misc/ssfilter.h
index 53922a844457..c7db8eee9578 100644
--- a/misc/ssfilter.h
+++ b/misc/ssfilter.h
@@ -8,6 +8,7 @@
 #define SSF_S_GE  7
 #define SSF_S_LE  8
 #define SSF_S_AUTO  9
+#define SSF_DEVCOND 10
 
 #include <stdbool.h>
 
@@ -20,3 +21,4 @@ struct ssfilter
 
 int ssfilter_parse(struct ssfilter **f, int argc, char **argv, FILE *fp);
 void *parse_hostcond(char *addr, bool is_port);
+void *parse_devcond(char *name);
diff --git a/misc/ssfilter.y b/misc/ssfilter.y
index a258d04b85d7..14bf9817f2c3 100644
--- a/misc/ssfilter.y
+++ b/misc/ssfilter.y
@@ -36,7 +36,7 @@ static void yyerror(char *s)
 
 %}
 
-%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND
+%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND DEVCOND DEVNAME
 %left '|'
 %left '&'
 %nonassoc '!'
@@ -108,6 +108,14 @@ expr:	DCOND HOSTCOND
         {
 		$$ = alloc_node(SSF_NOT, alloc_node(SSF_SCOND, $3));
         }
+        | DEVNAME '=' DEVCOND
+        {
+		$$ = alloc_node(SSF_DEVCOND, $3);
+        }
+        | DEVNAME NEQ DEVCOND
+        {
+		$$ = alloc_node(SSF_NOT, alloc_node(SSF_DEVCOND, $3));
+        }
 
         | AUTOBOUND
         {
@@ -237,6 +245,10 @@ int yylex(void)
 		tok_type = SPORT;
 		return SPORT;
 	}
+	if (strcmp(curtok, "dev") == 0) {
+		tok_type = DEVNAME;
+		return DEVNAME;
+	}
 	if (strcmp(curtok, ">=") == 0 ||
 	    strcmp(curtok, "ge") == 0 ||
 	    strcmp(curtok, "geq") == 0)
@@ -263,6 +275,14 @@ int yylex(void)
 		tok_type = AUTOBOUND;
 		return AUTOBOUND;
 	}
+	if (tok_type == DEVNAME) {
+		yylval = (void*)parse_devcond(curtok);
+		if (yylval == NULL) {
+			fprintf(stderr, "Cannot parse device.\n");
+			exit(1);
+		}
+		return DEVCOND;
+	}
 	yylval = (void*)parse_hostcond(curtok, tok_type == SPORT || tok_type == DPORT);
 	if (yylval == NULL) {
 		fprintf(stderr, "Cannot parse dst/src address.\n");
-- 
2.1.4

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

* Re: [PATCH v2 iproute2 3/3] ss: Add support to filter on device
  2016-06-27 18:34 ` [PATCH v2 iproute2 3/3] ss: Add support to filter on device David Ahern
@ 2016-06-27 21:13   ` Stephen Hemminger
  2016-06-28 17:40     ` David Ahern
  0 siblings, 1 reply; 7+ messages in thread
From: Stephen Hemminger @ 2016-06-27 21:13 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev

On Mon, 27 Jun 2016 11:34:25 -0700
David Ahern <dsa@cumulusnetworks.com> wrote:

> +		case SSF_DEVCOND:
> +	{
> +		struct aafilter *a = (void *)f->pred;

I don't like the wandering bracket left, but all the code has that.
After this will change it to:
		case SSF_DEVCOND:  {
			struct aafilter *a = f->pred;
...

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

* Re: [PATCH v2 iproute2 3/3] ss: Add support to filter on device
  2016-06-27 21:13   ` Stephen Hemminger
@ 2016-06-28 17:40     ` David Ahern
  2016-06-29  0:11       ` Stephen Hemminger
  0 siblings, 1 reply; 7+ messages in thread
From: David Ahern @ 2016-06-28 17:40 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

On 6/27/16 3:13 PM, Stephen Hemminger wrote:
> On Mon, 27 Jun 2016 11:34:25 -0700
> David Ahern <dsa@cumulusnetworks.com> wrote:
>
>> +		case SSF_DEVCOND:
>> +	{
>> +		struct aafilter *a = (void *)f->pred;
>
> I don't like the wandering bracket left, but all the code has that.
> After this will change it to:
> 		case SSF_DEVCOND:  {
> 			struct aafilter *a = f->pred;
> ...
>

meaning you'll take the patches as is since they follow current 
formatting and you will apply a patch to fix the indentation in that 
run_ssfilter? They have not shown up in your repo so want to make sure I 
understand the intent.

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

* Re: [PATCH v2 iproute2 3/3] ss: Add support to filter on device
  2016-06-28 17:40     ` David Ahern
@ 2016-06-29  0:11       ` Stephen Hemminger
  0 siblings, 0 replies; 7+ messages in thread
From: Stephen Hemminger @ 2016-06-29  0:11 UTC (permalink / raw)
  To: David Ahern; +Cc: netdev

On Tue, 28 Jun 2016 11:40:40 -0600
David Ahern <dsa@cumulusnetworks.com> wrote:

> On 6/27/16 3:13 PM, Stephen Hemminger wrote:
> > On Mon, 27 Jun 2016 11:34:25 -0700
> > David Ahern <dsa@cumulusnetworks.com> wrote:
> >  
> >> +		case SSF_DEVCOND:
> >> +	{
> >> +		struct aafilter *a = (void *)f->pred;  
> >
> > I don't like the wandering bracket left, but all the code has that.
> > After this will change it to:
> > 		case SSF_DEVCOND:  {
> > 			struct aafilter *a = f->pred;
> > ...
> >  
> 
> meaning you'll take the patches as is since they follow current 
> formatting and you will apply a patch to fix the indentation in that 
> run_ssfilter? They have not shown up in your repo so want to make sure I 
> understand the intent.

They all got applied today

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

end of thread, other threads:[~2016-06-29  0:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-27 18:34 [PATCH v2 iproute2 0/3] ss: Add support to filter by device David Ahern
2016-06-27 18:34 ` [PATCH v2 iproute2 1/3] ss: Refactor inet_show_sock David Ahern
2016-06-27 18:34 ` [PATCH v2 iproute2 2/3] ss: Allow ssfilter_bytecompile to return 0 David Ahern
2016-06-27 18:34 ` [PATCH v2 iproute2 3/3] ss: Add support to filter on device David Ahern
2016-06-27 21:13   ` Stephen Hemminger
2016-06-28 17:40     ` David Ahern
2016-06-29  0:11       ` 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.