[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1467052465-14488-4-git-send-email-dsa@cumulusnetworks.com>
Date: Mon, 27 Jun 2016 11:34:25 -0700
From: David Ahern <dsa@...ulusnetworks.com>
To: netdev@...r.kernel.org
Cc: stephen@...workplumber.org, David Ahern <dsa@...ulusnetworks.com>
Subject: [PATCH v2 iproute2 3/3] ss: Add support to filter on device
Add support for device names in the filter. Example:
root@...ny:~# 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@...ulusnetworks.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
Powered by blists - more mailing lists