mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-05 05:31:20 +00:00
ss: Add support to filter on device
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>
This commit is contained in:
parent
376fb86872
commit
2d29321256
32
misc/ss.c
32
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);
|
||||
@ -1327,6 +1333,11 @@ static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode)
|
||||
*(struct inet_diag_bc_op *)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, 8 };
|
||||
*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;
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user