naccyde / rpms / iproute

Forked from rpms/iproute 5 months ago
Clone

Blame SOURCES/0147-ss-Fix-wrong-filter-behaviour.patch

049c96
From d57e50c6402fb84b9fb21617a9e4e69551af50f2 Mon Sep 17 00:00:00 2001
049c96
From: Phil Sutter <psutter@redhat.com>
049c96
Date: Mon, 30 May 2016 16:46:58 +0200
049c96
Subject: [PATCH] ss: Fix wrong filter behaviour
049c96
049c96
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1318005
049c96
Upstream Status: iproute2.git commit 57ff5a1096cab
049c96
049c96
commit 57ff5a1096cab63107d7e85bcd0d822614e33d73
049c96
Author: Vadim Kochan <vadim4j@gmail.com>
049c96
Date:   Thu Apr 30 07:30:24 2015 +0300
049c96
049c96
    ss: Fix wrong filter behaviour
049c96
049c96
    Fixed applying family & socket type filters.
049c96
    It was not possible to select UDP & UNIX sockets together.
049c96
049c96
    Now selected families are ORed.
049c96
049c96
    The problem was that filters were combined by AND.
049c96
049c96
    Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
049c96
    Reported-By: Mihai Moldovan <ionic@ionic.de>
049c96
---
049c96
 misc/ss.c | 91 ++++++++++++++++++++++++++++++++++-----------------------------
049c96
 1 file changed, 49 insertions(+), 42 deletions(-)
049c96
049c96
diff --git a/misc/ss.c b/misc/ss.c
049c96
index 7750887..95f3c31 100644
049c96
--- a/misc/ss.c
049c96
+++ b/misc/ss.c
049c96
@@ -233,14 +233,12 @@ static struct filter current_filter;
049c96
 static void filter_db_set(struct filter *f, int db)
049c96
 {
049c96
 	f->states   |= default_dbs[db].states;
049c96
-	f->families |= default_dbs[db].families;
049c96
 	f->dbs	    |= 1 << db;
049c96
 	do_default   = 0;
049c96
 }
049c96
 
049c96
 static void filter_af_set(struct filter *f, int af)
049c96
 {
049c96
-	f->dbs		   |= default_afs[af].dbs;
049c96
 	f->states	   |= default_afs[af].states;
049c96
 	f->families	   |= 1 << af;
049c96
 	do_default	    = 0;
049c96
@@ -266,21 +264,31 @@ static void filter_default_dbs(struct filter *f)
049c96
 	filter_db_set(f, NETLINK_DB);
049c96
 }
049c96
 
049c96
-static void filter_merge(struct filter *af, struct filter *dbf, int states)
049c96
+static void filter_states_set(struct filter *f, int states)
049c96
 {
049c96
-	if (af->families)
049c96
-		af->families = (af->families | dbf->families) & af->families;
049c96
-	else
049c96
-		af->families = dbf->families;
049c96
+	if (states)
049c96
+		f->states = (f->states | states) & states;
049c96
+}
049c96
 
049c96
-	if (dbf->dbs)
049c96
-		af->dbs = (af->dbs | dbf->dbs) & dbf->dbs;
049c96
+static void filter_merge_defaults(struct filter *f)
049c96
+{
049c96
+	int db;
049c96
+	int af;
049c96
 
049c96
-	if (dbf->states)
049c96
-		af->states = (af->states | dbf->states) & dbf->states;
049c96
+	for (db = 0; db < MAX_DB; db++) {
049c96
+		if (!(f->dbs & (1 << db)))
049c96
+			continue;
049c96
 
049c96
-	if (states)
049c96
-		af->states = (af->states | states) & states;
049c96
+		if (!(default_dbs[db].families & f->families))
049c96
+			f->families |= default_dbs[db].families;
049c96
+	}
049c96
+	for (af = 0; af < AF_MAX; af++) {
049c96
+		if (!(f->families & (1 << af)))
049c96
+			continue;
049c96
+
049c96
+		if (!(default_afs[af].dbs & f->dbs))
049c96
+			f->dbs |= default_afs[af].dbs;
049c96
+	}
049c96
 }
049c96
 
049c96
 static FILE *generic_proc_open(const char *env, const char *name)
049c96
@@ -1540,7 +1548,7 @@ out:
049c96
 	if (fam != AF_UNSPEC) {
049c96
 		f->families = 0;
049c96
 		filter_af_set(f, fam);
049c96
-		filter_merge(f, f, 0);
049c96
+		filter_states_set(f, 0);
049c96
 	}
049c96
 
049c96
 	res = malloc(sizeof(*res));
049c96
@@ -3440,7 +3448,6 @@ int main(int argc, char *argv[])
049c96
 	const char *dump_tcpdiag = NULL;
049c96
 	FILE *filter_fp = NULL;
049c96
 	int ch;
049c96
-	struct filter dbs_filter = {};
049c96
 	int state_filter = 0;
049c96
 
049c96
 	while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbf:miA:D:F:vVzZN:",
049c96
@@ -3474,16 +3481,16 @@ int main(int argc, char *argv[])
049c96
 			show_bpf++;
049c96
 			break;
049c96
 		case 'd':
049c96
-			filter_db_set(&dbs_filter, DCCP_DB);
049c96
+			filter_db_set(&current_filter, DCCP_DB);
049c96
 			break;
049c96
 		case 't':
049c96
-			filter_db_set(&dbs_filter, TCP_DB);
049c96
+			filter_db_set(&current_filter, TCP_DB);
049c96
 			break;
049c96
 		case 'u':
049c96
-			filter_db_set(&dbs_filter, UDP_DB);
049c96
+			filter_db_set(&current_filter, UDP_DB);
049c96
 			break;
049c96
 		case 'w':
049c96
-			filter_db_set(&dbs_filter, RAW_DB);
049c96
+			filter_db_set(&current_filter, RAW_DB);
049c96
 			break;
049c96
 		case 'x':
049c96
 			filter_af_set(&current_filter, AF_UNIX);
049c96
@@ -3537,44 +3544,44 @@ int main(int argc, char *argv[])
049c96
 				if ((p1 = strchr(p, ',')) != NULL)
049c96
 					*p1 = 0;
049c96
 				if (strcmp(p, "all") == 0) {
049c96
-					filter_default_dbs(&dbs_filter);
049c96
+					filter_default_dbs(&current_filter);
049c96
 				} else if (strcmp(p, "inet") == 0) {
049c96
-					filter_db_set(&dbs_filter, UDP_DB);
049c96
-					filter_db_set(&dbs_filter, DCCP_DB);
049c96
-					filter_db_set(&dbs_filter, TCP_DB);
049c96
-					filter_db_set(&dbs_filter, RAW_DB);
049c96
+					filter_db_set(&current_filter, UDP_DB);
049c96
+					filter_db_set(&current_filter, DCCP_DB);
049c96
+					filter_db_set(&current_filter, TCP_DB);
049c96
+					filter_db_set(&current_filter, RAW_DB);
049c96
 				} else if (strcmp(p, "udp") == 0) {
049c96
-					filter_db_set(&dbs_filter, UDP_DB);
049c96
+					filter_db_set(&current_filter, UDP_DB);
049c96
 				} else if (strcmp(p, "dccp") == 0) {
049c96
-					filter_db_set(&dbs_filter, DCCP_DB);
049c96
+					filter_db_set(&current_filter, DCCP_DB);
049c96
 				} else if (strcmp(p, "tcp") == 0) {
049c96
-					filter_db_set(&dbs_filter, TCP_DB);
049c96
+					filter_db_set(&current_filter, TCP_DB);
049c96
 				} else if (strcmp(p, "raw") == 0) {
049c96
-					filter_db_set(&dbs_filter, RAW_DB);
049c96
+					filter_db_set(&current_filter, RAW_DB);
049c96
 				} else if (strcmp(p, "unix") == 0) {
049c96
-					filter_db_set(&dbs_filter, UNIX_ST_DB);
049c96
-					filter_db_set(&dbs_filter, UNIX_DG_DB);
049c96
-					filter_db_set(&dbs_filter, UNIX_SQ_DB);
049c96
+					filter_db_set(&current_filter, UNIX_ST_DB);
049c96
+					filter_db_set(&current_filter, UNIX_DG_DB);
049c96
+					filter_db_set(&current_filter, UNIX_SQ_DB);
049c96
 				} else if (strcasecmp(p, "unix_stream") == 0 ||
049c96
 					   strcmp(p, "u_str") == 0) {
049c96
-					filter_db_set(&dbs_filter, UNIX_ST_DB);
049c96
+					filter_db_set(&current_filter, UNIX_ST_DB);
049c96
 				} else if (strcasecmp(p, "unix_dgram") == 0 ||
049c96
 					   strcmp(p, "u_dgr") == 0) {
049c96
-					filter_db_set(&dbs_filter, UNIX_DG_DB);
049c96
+					filter_db_set(&current_filter, UNIX_DG_DB);
049c96
 				} else if (strcasecmp(p, "unix_seqpacket") == 0 ||
049c96
 					   strcmp(p, "u_seq") == 0) {
049c96
-					filter_db_set(&dbs_filter, UNIX_SQ_DB);
049c96
+					filter_db_set(&current_filter, UNIX_SQ_DB);
049c96
 				} else if (strcmp(p, "packet") == 0) {
049c96
-					filter_db_set(&dbs_filter, PACKET_R_DB);
049c96
-					filter_db_set(&dbs_filter, PACKET_DG_DB);
049c96
+					filter_db_set(&current_filter, PACKET_R_DB);
049c96
+					filter_db_set(&current_filter, PACKET_DG_DB);
049c96
 				} else if (strcmp(p, "packet_raw") == 0 ||
049c96
 					   strcmp(p, "p_raw") == 0) {
049c96
-					filter_db_set(&dbs_filter, PACKET_R_DB);
049c96
+					filter_db_set(&current_filter, PACKET_R_DB);
049c96
 				} else if (strcmp(p, "packet_dgram") == 0 ||
049c96
 					   strcmp(p, "p_dgr") == 0) {
049c96
-					filter_db_set(&dbs_filter, PACKET_DG_DB);
049c96
+					filter_db_set(&current_filter, PACKET_DG_DB);
049c96
 				} else if (strcmp(p, "netlink") == 0) {
049c96
-					filter_db_set(&dbs_filter, NETLINK_DB);
049c96
+					filter_db_set(&current_filter, NETLINK_DB);
049c96
 				} else {
049c96
 					fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
049c96
 					usage();
049c96
@@ -3667,11 +3674,11 @@ int main(int argc, char *argv[])
049c96
 	if (do_default) {
049c96
 		state_filter = state_filter ? state_filter : SS_CONN;
049c96
 		filter_default_dbs(&current_filter);
049c96
-		filter_merge(&current_filter, &current_filter, state_filter);
049c96
-	} else {
049c96
-		filter_merge(&current_filter, &dbs_filter, state_filter);
049c96
 	}
049c96
 
049c96
+	filter_states_set(&current_filter, state_filter);
049c96
+	filter_merge_defaults(&current_filter);
049c96
+
049c96
 	if (resolve_services && resolve_hosts &&
049c96
 	    (current_filter.dbs&(UNIX_DBM|(1<
049c96
 		init_service_resolver();
049c96
-- 
049c96
1.8.3.1
049c96