Netdev List
 help / color / mirror / Atom feed
* [PATCH iproute2 v3 1/3] ss: Unify unix stats output from netlink and proc
From: Vadim Kochan @ 2015-01-04 20:18 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1420402720-28767-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Refactored to use one func for output unix stats info
from both /proc and netlink.

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 99 ++++++++++++++++++++++++---------------------------------------
 1 file changed, 37 insertions(+), 62 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index f0c7b34..4dde080 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -25,6 +25,7 @@
 #include <dirent.h>
 #include <fnmatch.h>
 #include <getopt.h>
+#include <stdbool.h>
 
 #include "utils.h"
 #include "rt_names.h"
@@ -2234,6 +2235,7 @@ struct unixstat
 	struct unixstat *next;
 	int ino;
 	int peer;
+	char *peer_name;
 	int rq;
 	int wq;
 	int state;
@@ -2279,7 +2281,18 @@ static const char *unix_netid_name(int type)
 	return netid;
 }
 
-static void unix_list_print(struct unixstat *list, struct filter *f)
+static bool unix_type_skip(struct unixstat *s, struct filter *f)
+{
+	if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
+		return true;
+	if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
+		return true;
+	if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
+		return true;
+	return false;
+}
+
+static void unix_stats_print(struct unixstat *list, struct filter *f)
 {
 	struct unixstat *s;
 	char *peer;
@@ -2287,15 +2300,14 @@ static void unix_list_print(struct unixstat *list, struct filter *f)
 	for (s = list; s; s = s->next) {
 		if (!(f->states & (1<<s->state)))
 			continue;
-		if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
-			continue;
-		if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
-			continue;
-		if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
+		if (unix_type_skip(s, f))
 			continue;
 
 		peer = "*";
-		if (s->peer) {
+		if (s->peer_name)
+			peer = s->peer_name;
+
+		if (s->peer && !s->peer_name) {
 			struct unixstat *p;
 			for (p = list; p; p = p->next) {
 				if (s->peer == p->ino)
@@ -2356,36 +2368,23 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 	struct unix_diag_msg *r = NLMSG_DATA(nlh);
 	struct rtattr *tb[UNIX_DIAG_MAX+1];
 	char name[128];
-	int peer_ino;
-	__u32 rqlen, wqlen;
+	struct unixstat stat = { .name = "*" , .peer_name = "*" };
 
 	parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
 		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
-	if (r->udiag_type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
-		return 0;
-	if (r->udiag_type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
-		return 0;
-	if (r->udiag_type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
-		return 0;
+	stat.type  = r->udiag_type;
+	stat.state = r->udiag_state;
+	stat.ino   = r->udiag_ino;
 
-	if (netid_width)
-		printf("%-*s ", netid_width,
-		       unix_netid_name(r->udiag_type));
-	if (state_width)
-		printf("%-*s ", state_width, sstate_name[r->udiag_state]);
+	if (unix_type_skip(&stat, f))
+		return 0;
 
 	if (tb[UNIX_DIAG_RQLEN]) {
 		struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
-		rqlen = rql->udiag_rqueue;
-		wqlen = rql->udiag_wqueue;
-	} else {
-		rqlen = 0;
-		wqlen = 0;
+		stat.rq = rql->udiag_rqueue;
+		stat.wq = rql->udiag_wqueue;
 	}
-
-	printf("%-6u %-6u ", rqlen, wqlen);
-
 	if (tb[UNIX_DIAG_NAME]) {
 		int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
 
@@ -2393,41 +2392,17 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 		name[len] = '\0';
 		if (name[0] == '\0')
 			name[0] = '@';
-	} else
-		sprintf(name, "*");
-
+		stat.name = &name[0];
+	}
 	if (tb[UNIX_DIAG_PEER])
-		peer_ino = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
-	else
-		peer_ino = 0;
+		stat.peer = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
 
-	printf("%*s %-*d %*s %-*d",
-			addr_width, name,
-			serv_width, r->udiag_ino,
-			addr_width, "*", /* FIXME */
-			serv_width, peer_ino);
-
-	char *buf = NULL;
-
-	if (show_proc_ctx || show_sock_ctx) {
-		if (find_entry(r->udiag_ino, &buf,
-				(show_proc_ctx & show_sock_ctx) ?
-				PROC_SOCK_CTX : PROC_CTX) > 0) {
-			printf(" users:(%s)", buf);
-			free(buf);
-		}
-	} else if (show_users) {
-		if (find_entry(r->udiag_ino, &buf, USERS) > 0) {
-			printf(" users:(%s)", buf);
-			free(buf);
-		}
-	}
+	unix_stats_print(&stat, f);
 
 	if (show_mem) {
-		printf("\n\t");
+		printf("\t");
 		print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
 	}
-
 	if (show_details) {
 		if (tb[UNIX_DIAG_SHUTDOWN]) {
 			unsigned char mask;
@@ -2435,9 +2410,8 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 			printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
 		}
 	}
-
-	printf("\n");
-
+	if (show_mem || show_details)
+		printf("\n");
 	return 0;
 }
 
@@ -2505,6 +2479,7 @@ static int unix_show(struct filter *f)
 		if (!(u = malloc(sizeof(*u))))
 			break;
 		u->name = NULL;
+		u->peer_name = NULL;
 
 		if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
 			   &u->peer, &u->rq, &u->wq, &flags, &u->type,
@@ -2544,7 +2519,7 @@ static int unix_show(struct filter *f)
 			strcpy(u->name, name);
 		}
 		if (++cnt > MAX_UNIX_REMEMBER) {
-			unix_list_print(list, f);
+			unix_stats_print(list, f);
 			unix_list_free(list);
 			list = NULL;
 			cnt = 0;
@@ -2552,7 +2527,7 @@ static int unix_show(struct filter *f)
 	}
 	fclose(fp);
 	if (list) {
-		unix_list_print(list, f);
+		unix_stats_print(list, f);
 		unix_list_free(list);
 		list = NULL;
 		cnt = 0;
-- 
2.1.3

^ permalink raw reply related

* [PATCH iproute2 v3 0/3] ss: Fix sockets filtering
From: Vadim Kochan @ 2015-01-04 20:18 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan

From: Vadim Kochan <vadim4j@gmail.com>

v3:
    patch #2:
        Used correct types in pktstat struct
v2:
    patch #1
        1) Used bool and true/false

    patch #3:
        1) Added 'const' to 'filter' tables in patch #3
        3) Get rid of default_filter
        4) Changed a little bit merging of filtering options
        5) Now packet and netlink show funcs requires AF and SS_CLOSE to be set
 
This series contains refactoring & fixes related to sockets filtering.

1st 2 patches relates mostly to refactoring as they just
allows to use one func to output UNIX & PACKET socket stats from both Netlink &
/proc.

The last one have a big change which related to the way how filtering options
are combined with each other. This change has also fixes for some filtering
combination options.

I did some basic testing *BUT* I cant guarantee that there is no bugs ...
Here is my some testing list with comparing to the 'master' version:

Some test results with comparing version in PATCH and version from master
-------------------------------------------------------------------------

this   - ss version sending in PATCH
master - ss version in master

Case #1: Show only IPv4 sockets
    $ ss -4

    RESULTS
        this    -  shows only IPv4 sockets with established states     [OK]
        master  -  shows IPv4 and UNIX sockets with established states [FAIL]

Case #2: Show only IPv4 sockets with all states
    $ ss -4 -a

    RESULTS
        this    -  shows only IPv4 sockets with all states [OK]
        master  -  shows ALL sockets kinds with all states [FAIL]

Case #3: Show only IPv4 sockets with listen states (closed or listening)
    $ ss -4 -l

    RESULTS
        this    -  shows only IPv4 sockets with listen states    [OK]
        master  -  shows ALL sockets kinds with LISTENING states [FAIL]

Case #4 Show only IPv4 UDP sockets
    $ ss -4 -u

    RESULTS
        this    -  shows only IPv4 UDP sockets                                 [OK]
        master  -  shows IPv4 UDP sockets but only if state 'closed' specified [FAIL]
    
    In 'this' version it is not needed to set 'closed' state additionally for UDP sockets as it it set
    automatically because we explicitly specified UDP sockets. 

Case #5: Show all UDP sockets
    $ ss -u

    RESULTS
        this    -  shows all UDP sockets for both IPv4/IPv6 protocol families  [OK]
        master  -  shows IPv4 UDP sockets but only if state 'closed' specified [FAIL]

Case #6: Show all UDP sockets for IPv6 only protocol
    $ ss -u -6

    RESULTS
        this    -  shows all IPv6 UDP sockets                                  [OK]
        master  -  shows IPv4 UDP sockets but only if state 'closed' specified [FAIL]


Case #7: Show UNIX sockets with matches "*X11*" as src
    $ ss src unix:*X11*

    RESULTS
        this    -  shows only UNIX sockets with established states with src matches "*X11*" [OK]
        master  -  shows all established UNIX sockets with "RTNETLINK" errors               [FAIL]


Case #8: Show UNIX sockets with matches "*X11*" as src but with LISTENING states only
    $ ss src unix:*X11* -l

    RESULTS
        this    -  shows only UNIX sockets with LISTENING states with src matches "*X11*" [OK]
        master  -  Segmentation error                                                     [FAIL]

Case #9: Show all RAW sockets
    $ ss -w

    RESULTS
        this    - shows all RAW sockets for IPv4/IPv6 families                                  [OK]
        master  - shows all RAW sockets for IPv4/IPv6 families only if state 'closed' specified [FAIL]

Case #10: Show all TCP/UDP sockets
    $ ss -t -u

    RESULTS
        this    - shows all established TCP and unconnected UDP sockets for IPv4/IPv6 protocols. [OK]
        master  - shows only TCP established sockets, shows UDP                                  [FAIL]

Vadim Kochan (3):
  ss: Unify unix stats output from netlink and proc
  ss: Unify packet stats output from netlink and proc
  ss: Filtering logic changing, with fixes

 misc/ss.c | 628 ++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 346 insertions(+), 282 deletions(-)

-- 
2.1.3

^ permalink raw reply

* [PATCH 1/2] Align member-assigns in a structure-copy block
From: Giel van Schijndel @ 2015-01-04 18:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: Giel van Schijndel, Kalle Valo, Eliad Peller, John W. Linville,
	Arik Nemtsov, open list:TI WILINK WIRELES...,
	open list:NETWORKING DRIVERS

This highlights the differences (errors).
---
 drivers/net/wireless/ti/wlcore/acx.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index b924cea..beb354c 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1715,17 +1715,17 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl)
 		goto out;
 	}
 
-	acx->recover_time = cpu_to_le32(conf->recover_time);
-	acx->hangover_period = conf->hangover_period;
-	acx->dynamic_mode = conf->dynamic_mode;
-	acx->early_termination_mode = conf->early_termination_mode;
-	acx->max_period = conf->max_period;
-	acx->min_period = conf->min_period;
-	acx->increase_delta = conf->increase_delta;
-	acx->decrease_delta = conf->decrease_delta;
-	acx->quiet_time = conf->quiet_time;
-	acx->increase_time = conf->increase_time;
-	acx->window_size = acx->window_size;
+	acx->recover_time               = cpu_to_le32(conf->recover_time);
+	acx->hangover_period            = conf->hangover_period;
+	acx->dynamic_mode               = conf->dynamic_mode;
+	acx->early_termination_mode     = conf->early_termination_mode;
+	acx->max_period                 = conf->max_period;
+	acx->min_period                 = conf->min_period;
+	acx->increase_delta             = conf->increase_delta;
+	acx->decrease_delta             = conf->decrease_delta;
+	acx->quiet_time                 = conf->quiet_time;
+	acx->increase_time              = conf->increase_time;
+	acx->window_size                = acx->window_size;
 
 	ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx,
 				   sizeof(*acx));
-- 
2.1.4

^ permalink raw reply related

* [PATCH] Fix NUL (\0 or \x00) specification in string
From: Giel van Schijndel @ 2015-01-04 18:05 UTC (permalink / raw)
  To: linux-kernel
  Cc: Giel van Schijndel, Armin Schindler, Karsten Keil,
	open list:ISDN SUBSYSTEM

In C one can either use '\0' or '\x00' (or '\000') to add a NUL byte to
a string. '\0x00' isn't part of these and will in fact result in a
single NUL followed by "x00". This fixes that.
---
 drivers/isdn/hardware/eicon/message.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index a82e542..0b38060 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -4880,7 +4880,7 @@ static void sig_ind(PLCI *plci)
 	byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
 	byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
 	byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-	byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00";
+	byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00";
 	byte force_mt_info = false;
 	byte dir;
 	dword d;
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH iproute2 v2 2/3] ss: Unify packet stats output from netlink and proc
From: Vadim Kochan @ 2015-01-04 18:32 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Vadim Kochan, netdev
In-Reply-To: <20150104103008.1648dcb8@urahara>

On Sun, Jan 04, 2015 at 10:30:08AM -0800, Stephen Hemminger wrote:
> On Sun,  4 Jan 2015 19:20:54 +0200
> Vadim Kochan <vadim4j@gmail.com> wrote:
> 
> > +struct pktstat {
> > +	int type;
> > +	int prot;
> > +	int iface;
> > +	int state;
> > +	int rq;
> > +	int uid;
> > +	int ino;
> > +};
> 
> Rather than copying the original data types, this structure should use the
> correct types that already exist. 
> For example: type is pdiag_type which is __u8 therefore it should be __u8 or uint8_t.
> 
> Likewise uid should be uid_t etc.

Thats good point, but it would be good to do this for all xxxstats
struct's, may be in separated patch ?

Regards,

^ permalink raw reply

* Re: [PATCH iproute2 v2 2/3] ss: Unify packet stats output from netlink and proc
From: Stephen Hemminger @ 2015-01-04 18:30 UTC (permalink / raw)
  To: Vadim Kochan; +Cc: netdev
In-Reply-To: <1420392055-4754-3-git-send-email-vadim4j@gmail.com>

On Sun,  4 Jan 2015 19:20:54 +0200
Vadim Kochan <vadim4j@gmail.com> wrote:

> +struct pktstat {
> +	int type;
> +	int prot;
> +	int iface;
> +	int state;
> +	int rq;
> +	int uid;
> +	int ino;
> +};

Rather than copying the original data types, this structure should use the
correct types that already exist. 
For example: type is pdiag_type which is __u8 therefore it should be __u8 or uint8_t.

Likewise uid should be uid_t etc.

^ permalink raw reply

* [PATCH] Fix an infinite retry-loop
From: Giel van Schijndel @ 2015-01-04 18:04 UTC (permalink / raw)
  To: linux-kernel
  Cc: Giel van Schijndel, Jitendra Kalsaria, Ron Mercer,
	supporter:QLOGIC QLA3XXX NE..., open list:QLOGIC QLA3XXX NE...

This was clearly intended as a retry-10-times loop, but due to the
absence of code incrementing the loop-counter it was practically a
retry-forever loop.

Rewritten it as a for-loop as well to make the loop-counter increment
(as well as its potential absence) easier to spot.
---
 drivers/net/ethernet/qlogic/qla3xxx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index c2f09af..35a26c9 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -144,9 +144,9 @@ static int ql_sem_lock(struct ql3_adapter *qdev, u32 sem_mask, u32 sem_bits)
  */
 static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev)
 {
-	int i = 0;
+	int i;
 
-	while (i < 10) {
+	for (i = 0; i < 10; ++i) {
 		if (i)
 			ssleep(1);
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH 2/2] Fix copy-paste bug: assign from src struct not dest
From: Giel van Schijndel @ 2015-01-04 18:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: Giel van Schijndel, Kalle Valo, Eliad Peller, John W. Linville,
	Arik Nemtsov, open list:TI WILINK WIRELES...,
	open list:NETWORKING DRIVERS
In-Reply-To: <1420394427-19509-1-git-send-email-me@mortis.eu>

---
 drivers/net/wireless/ti/wlcore/acx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index beb354c..93a2fa8 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1725,7 +1725,7 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl)
 	acx->decrease_delta             = conf->decrease_delta;
 	acx->quiet_time                 = conf->quiet_time;
 	acx->increase_time              = conf->increase_time;
-	acx->window_size                = acx->window_size;
+	acx->window_size                = conf->window_size;
 
 	ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx,
 				   sizeof(*acx));
-- 
2.1.4

^ permalink raw reply related

* [PATCH iproute2 v2 3/3] ss: Filtering logic changing, with fixes
From: Vadim Kochan @ 2015-01-04 17:20 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1420392055-4754-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

This patch fixes some filtering combinations issues which does not
work on the 'master' version:

    $ ss -4
    shows inet & unix sockets, instead of only inet sockets

    $ ss -u
    needs to specify 'state closed'

    $ ss src unix:*X11*
    needs to specify '-x' shortcut for UNIX family

    $ ss -A all
    shows only sockets with established states

There might some other issues which was not observed.

Also changed logic for calculating families, socket types and
states filtering. I think that this version is a little simpler
one. Now there are 2 predefined default tables which describes
the following maping:

    family  -> (states, dbs)
    db      -> (states, families)

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 318 ++++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 207 insertions(+), 111 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 20d3f75..d64d831 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -129,6 +129,7 @@ enum
 #define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB))
 #define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)|(1<<UNIX_SQ_DB))
 #define ALL_DB ((1<<MAX_DB)-1)
+#define INET_DBM ((1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)|(1<<RAW_DB))
 
 enum {
 	SS_UNKNOWN,
@@ -146,7 +147,8 @@ enum {
 	SS_MAX
 };
 
-#define SS_ALL ((1<<SS_MAX)-1)
+#define SS_ALL ((1 << SS_MAX) - 1)
+#define SS_CONN (SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)))
 
 #include "ssfilter.h"
 
@@ -158,13 +160,126 @@ struct filter
 	struct ssfilter *f;
 };
 
-struct filter default_filter = {
-	.dbs	=  ~0,
-	.states = SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)),
-	.families= (1<<AF_INET)|(1<<AF_INET6),
+const struct filter default_dbs[MAX_DB] = {
+	[TCP_DB] = {
+		.states   = SS_CONN,
+		.families = (1 << AF_INET) | (1 << AF_INET6),
+	},
+	[DCCP_DB] = {
+		.states   = SS_CONN,
+		.families = (1 << AF_INET) | (1 << AF_INET6),
+	},
+	[UDP_DB] = {
+		.states   = (1 << SS_CLOSE),
+		.families = (1 << AF_INET) | (1 << AF_INET6),
+	},
+	[RAW_DB] = {
+		.states   = (1 << SS_CLOSE),
+		.families = (1 << AF_INET) | (1 << AF_INET6),
+	},
+	[UNIX_DG_DB] = {
+		.states   = (1 << SS_CLOSE),
+		.families = (1 << AF_UNIX),
+	},
+	[UNIX_ST_DB] = {
+		.states   = SS_CONN,
+		.families = (1 << AF_UNIX),
+	},
+	[UNIX_SQ_DB] = {
+		.states   = SS_CONN,
+		.families = (1 << AF_UNIX),
+	},
+	[PACKET_DG_DB] = {
+		.states   = (1 << SS_CLOSE),
+		.families = (1 << AF_PACKET),
+	},
+	[PACKET_R_DB] = {
+		.states   = (1 << SS_CLOSE),
+		.families = (1 << AF_PACKET),
+	},
+	[NETLINK_DB] = {
+		.states   = (1 << SS_CLOSE),
+		.families = (1 << AF_NETLINK),
+	},
 };
 
-struct filter current_filter;
+const struct filter default_afs[AF_MAX] = {
+	[AF_INET] = {
+		.dbs    = INET_DBM,
+		.states = SS_CONN,
+	},
+	[AF_INET6] = {
+		.dbs    = INET_DBM,
+		.states = SS_CONN,
+	},
+	[AF_UNIX] = {
+		.dbs    = UNIX_DBM,
+		.states = SS_CONN,
+	},
+	[AF_PACKET] = {
+		.dbs    = PACKET_DBM,
+		.states = (1 << SS_CLOSE),
+	},
+	[AF_NETLINK] = {
+		.dbs    = (1 << NETLINK_DB),
+		.states = (1 << SS_CLOSE),
+	},
+};
+
+static int do_default = 1;
+static struct filter current_filter;
+
+static void filter_db_set(struct filter *f, int db)
+{
+	f->states   |= default_dbs[db].states;
+	f->families |= default_dbs[db].families;
+	f->dbs	    |= 1 << db;
+	do_default   = 0;
+}
+
+static void filter_af_set(struct filter *f, int af)
+{
+	f->dbs	    |= default_afs[af].dbs;
+	f->states   |= default_afs[af].states;
+	f->families |= 1 << af;
+	do_default   = 0;
+}
+
+static int filter_af_get(struct filter *f, int af)
+{
+	return f->families & (1 << af);
+}
+
+static void filter_default_dbs(struct filter *f)
+{
+	filter_db_set(f, UDP_DB);
+	filter_db_set(f, DCCP_DB);
+	filter_db_set(f, TCP_DB);
+	filter_db_set(f, RAW_DB);
+	filter_db_set(f, UNIX_ST_DB);
+	filter_db_set(f, UNIX_DG_DB);
+	filter_db_set(f, UNIX_SQ_DB);
+	filter_db_set(f, PACKET_R_DB);
+	filter_db_set(f, PACKET_DG_DB);
+	filter_db_set(f, NETLINK_DB);
+}
+
+static void filter_merge(struct filter *af, struct filter *dbf, int states)
+{
+	if (af->families)
+		af->families = (af->families | dbf->families) & af->families;
+	else
+		af->families = dbf->families;
+
+	if (dbf->dbs)
+		af->dbs = (af->dbs | dbf->dbs) & dbf->dbs;
+
+	if (dbf->states)
+		af->states = (af->states | dbf->states) & dbf->states;
+
+	if (states)
+		af->states = (af->states | states) & states;
+}
 
 static FILE *generic_proc_open(const char *env, const char *name)
 {
@@ -1172,12 +1287,13 @@ void *parse_hostcond(char *addr)
 	char *port = NULL;
 	struct aafilter a;
 	struct aafilter *res;
-	int fam = preferred_family;
+	int fam = 0;
+	struct filter *f = &current_filter;
 
 	memset(&a, 0, sizeof(a));
 	a.port = -1;
 
-	if (fam == AF_UNIX || strncmp(addr, "unix:", 5) == 0) {
+	if (filter_af_get(f, AF_UNIX) || strncmp(addr, "unix:", 5) == 0) {
 		char *p;
 		a.addr.family = AF_UNIX;
 		if (strncmp(addr, "unix:", 5) == 0)
@@ -1185,10 +1301,11 @@ void *parse_hostcond(char *addr)
 		p = strdup(addr);
 		a.addr.bitlen = 8*strlen(p);
 		memcpy(a.addr.data, &p, sizeof(p));
+		fam = AF_UNIX;
 		goto out;
 	}
 
-	if (fam == AF_PACKET || strncmp(addr, "link:", 5) == 0) {
+	if (filter_af_get(f, AF_PACKET) || strncmp(addr, "link:", 5) == 0) {
 		a.addr.family = AF_PACKET;
 		a.addr.bitlen = 0;
 		if (strncmp(addr, "link:", 5) == 0)
@@ -1210,10 +1327,11 @@ void *parse_hostcond(char *addr)
 				return NULL;
 			a.addr.data[0] = ntohs(tmp);
 		}
+		fam = AF_PACKET;
 		goto out;
 	}
 
-	if (fam == AF_NETLINK || strncmp(addr, "netlink:", 8) == 0) {
+	if (filter_af_get(f, AF_NETLINK) || strncmp(addr, "netlink:", 8) == 0) {
 		a.addr.family = AF_NETLINK;
 		a.addr.bitlen = 0;
 		if (strncmp(addr, "netlink:", 8) == 0)
@@ -1235,13 +1353,14 @@ void *parse_hostcond(char *addr)
 			if (nl_proto_a2n(&a.addr.data[0], addr) == -1)
 				return NULL;
 		}
+		fam = AF_NETLINK;
 		goto out;
 	}
 
-	if (strncmp(addr, "inet:", 5) == 0) {
+	if (filter_af_get(f, AF_INET) || !strncmp(addr, "inet:", 5)) {
 		addr += 5;
 		fam = AF_INET;
-	} else if (strncmp(addr, "inet6:", 6) == 0) {
+	} else if (filter_af_get(f, AF_INET6) || !strncmp(addr, "inet6:", 6)) {
 		addr += 6;
 		fam = AF_INET6;
 	}
@@ -1310,7 +1429,10 @@ void *parse_hostcond(char *addr)
 		}
 	}
 
-	out:
+out:
+	if (fam)
+		filter_af_set(f, fam);
+
 	res = malloc(sizeof(*res));
 	if (res)
 		memcpy(res, &a, sizeof(a));
@@ -2460,6 +2582,9 @@ static int unix_show(struct filter *f)
 	int  cnt;
 	struct unixstat *list = NULL;
 
+	if (!filter_af_get(f, AF_UNIX))
+		return 0;
+
 	if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT")
 	    && unix_show_netlink(f) == 0)
 		return 0;
@@ -2702,7 +2827,7 @@ static int packet_show(struct filter *f)
 {
 	FILE *fp;
 
-	if (preferred_family != AF_PACKET && !(f->states & (1 << SS_CLOSE)))
+	if (!filter_af_get(f, AF_PACKET) || !(f->states & (1 << SS_CLOSE)))
 		return 0;
 
 	if (!getenv("PROC_NET_PACKET") && !getenv("PROC_ROOT") &&
@@ -2870,7 +2995,7 @@ static int netlink_show(struct filter *f)
 	int rq, wq, rc;
 	unsigned long long sk, cb;
 
-	if (preferred_family != AF_NETLINK && !(f->states & (1 << SS_CLOSE)))
+	if (!filter_af_get(f, AF_NETLINK) || !(f->states & (1 << SS_CLOSE)))
 		return 0;
 
 	if (!getenv("PROC_NET_NETLINK") && !getenv("PROC_ROOT") &&
@@ -3133,7 +3258,9 @@ static int scan_state(const char *state)
 		if (strcasecmp(state, sstate_namel[i]) == 0)
 			return (1<<i);
 	}
-	return 0;
+
+	fprintf(stderr, "ss: wrong state name: %s\n", state);
+	exit(-1);
 }
 
 static const struct option long_opts[] = {
@@ -3171,17 +3298,14 @@ static const struct option long_opts[] = {
 
 int main(int argc, char *argv[])
 {
-	int do_default = 1;
 	int saw_states = 0;
 	int saw_query = 0;
 	int do_summary = 0;
 	const char *dump_tcpdiag = NULL;
 	FILE *filter_fp = NULL;
 	int ch;
-
-	memset(&current_filter, 0, sizeof(current_filter));
-
-	current_filter.states = default_filter.states;
+	struct filter dbs_filter = {};
+	int state_filter = 0;
 
 	while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbf:miA:D:F:vVzZ",
 				 long_opts, NULL)) != EOF) {
@@ -3214,55 +3338,51 @@ int main(int argc, char *argv[])
 			show_bpf++;
 			break;
 		case 'd':
-			current_filter.dbs |= (1<<DCCP_DB);
-			do_default = 0;
+			filter_db_set(&dbs_filter, DCCP_DB);
 			break;
 		case 't':
-			current_filter.dbs |= (1<<TCP_DB);
-			do_default = 0;
+			filter_db_set(&dbs_filter, TCP_DB);
 			break;
 		case 'u':
-			current_filter.dbs |= (1<<UDP_DB);
-			do_default = 0;
+			filter_db_set(&dbs_filter, UDP_DB);
 			break;
 		case 'w':
-			current_filter.dbs |= (1<<RAW_DB);
-			do_default = 0;
+			filter_db_set(&dbs_filter, RAW_DB);
 			break;
 		case 'x':
-			current_filter.dbs |= UNIX_DBM;
-			do_default = 0;
+			filter_af_set(&current_filter, AF_UNIX);
 			break;
 		case 'a':
-			current_filter.states = SS_ALL;
+			state_filter = SS_ALL;
 			break;
 		case 'l':
-			current_filter.states = (1<<SS_LISTEN) | (1<<SS_CLOSE);
+			state_filter = (1 << SS_LISTEN) | (1 << SS_CLOSE);
 			break;
 		case '4':
-			preferred_family = AF_INET;
+			filter_af_set(&current_filter, AF_INET);
 			break;
 		case '6':
-			preferred_family = AF_INET6;
+			filter_af_set(&current_filter, AF_INET6);
 			break;
 		case '0':
-			preferred_family = AF_PACKET;
+			filter_af_set(&current_filter, AF_PACKET);
 			break;
 		case 'f':
 			if (strcmp(optarg, "inet") == 0)
-				preferred_family = AF_INET;
+				filter_af_set(&current_filter, AF_INET);
 			else if (strcmp(optarg, "inet6") == 0)
-				preferred_family = AF_INET6;
+				filter_af_set(&current_filter, AF_INET6);
 			else if (strcmp(optarg, "link") == 0)
-				preferred_family = AF_PACKET;
+				filter_af_set(&current_filter, AF_PACKET);
 			else if (strcmp(optarg, "unix") == 0)
-				preferred_family = AF_UNIX;
+				filter_af_set(&current_filter, AF_UNIX);
 			else if (strcmp(optarg, "netlink") == 0)
-				preferred_family = AF_NETLINK;
+				filter_af_set(&current_filter, AF_NETLINK);
 			else if (strcmp(optarg, "help") == 0)
 				help();
 			else {
-				fprintf(stderr, "ss: \"%s\" is invalid family\n", optarg);
+				fprintf(stderr, "ss: \"%s\" is invalid family\n",
+						optarg);
 				usage();
 			}
 			break;
@@ -3279,38 +3399,44 @@ int main(int argc, char *argv[])
 				if ((p1 = strchr(p, ',')) != NULL)
 					*p1 = 0;
 				if (strcmp(p, "all") == 0) {
-					current_filter.dbs = ALL_DB;
+					filter_default_dbs(&dbs_filter);
 				} else if (strcmp(p, "inet") == 0) {
-					current_filter.dbs |= (1<<TCP_DB)|(1<<DCCP_DB)|(1<<UDP_DB)|(1<<RAW_DB);
+					filter_db_set(&dbs_filter, UDP_DB);
+					filter_db_set(&dbs_filter, DCCP_DB);
+					filter_db_set(&dbs_filter, TCP_DB);
+					filter_db_set(&dbs_filter, RAW_DB);
 				} else if (strcmp(p, "udp") == 0) {
-					current_filter.dbs |= (1<<UDP_DB);
+					filter_db_set(&dbs_filter, UDP_DB);
 				} else if (strcmp(p, "dccp") == 0) {
-					current_filter.dbs |= (1<<DCCP_DB);
+					filter_db_set(&dbs_filter, DCCP_DB);
 				} else if (strcmp(p, "tcp") == 0) {
-					current_filter.dbs |= (1<<TCP_DB);
+					filter_db_set(&dbs_filter, TCP_DB);
 				} else if (strcmp(p, "raw") == 0) {
-					current_filter.dbs |= (1<<RAW_DB);
+					filter_db_set(&dbs_filter, RAW_DB);
 				} else if (strcmp(p, "unix") == 0) {
-					current_filter.dbs |= UNIX_DBM;
+					filter_db_set(&dbs_filter, UNIX_ST_DB);
+					filter_db_set(&dbs_filter, UNIX_DG_DB);
+					filter_db_set(&dbs_filter, UNIX_SQ_DB);
 				} else if (strcasecmp(p, "unix_stream") == 0 ||
 					   strcmp(p, "u_str") == 0) {
-					current_filter.dbs |= (1<<UNIX_ST_DB);
+					filter_db_set(&dbs_filter, UNIX_ST_DB);
 				} else if (strcasecmp(p, "unix_dgram") == 0 ||
 					   strcmp(p, "u_dgr") == 0) {
-					current_filter.dbs |= (1<<UNIX_DG_DB);
+					filter_db_set(&dbs_filter, UNIX_DG_DB);
 				} else if (strcasecmp(p, "unix_seqpacket") == 0 ||
 					   strcmp(p, "u_seq") == 0) {
-					current_filter.dbs |= (1<<UNIX_SQ_DB);
+					filter_db_set(&dbs_filter, UNIX_SQ_DB);
 				} else if (strcmp(p, "packet") == 0) {
-					current_filter.dbs |= PACKET_DBM;
+					filter_db_set(&dbs_filter, PACKET_R_DB);
+					filter_db_set(&dbs_filter, PACKET_DG_DB);
 				} else if (strcmp(p, "packet_raw") == 0 ||
 					   strcmp(p, "p_raw") == 0) {
-					current_filter.dbs |= (1<<PACKET_R_DB);
+					filter_db_set(&dbs_filter, PACKET_R_DB);
 				} else if (strcmp(p, "packet_dgram") == 0 ||
 					   strcmp(p, "p_dgr") == 0) {
-					current_filter.dbs |= (1<<PACKET_DG_DB);
+					filter_db_set(&dbs_filter, PACKET_DG_DB);
 				} else if (strcmp(p, "netlink") == 0) {
-					current_filter.dbs |= (1<<NETLINK_DB);
+					filter_db_set(&dbs_filter, NETLINK_DB);
 				} else {
 					fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
 					usage();
@@ -3372,57 +3498,6 @@ int main(int argc, char *argv[])
 			exit(0);
 	}
 
-	if (do_default)
-		current_filter.dbs = default_filter.dbs;
-
-	if (preferred_family == AF_UNSPEC) {
-		if (!(current_filter.dbs&~UNIX_DBM))
-			preferred_family = AF_UNIX;
-		else if (!(current_filter.dbs&~PACKET_DBM))
-			preferred_family = AF_PACKET;
-		else if (!(current_filter.dbs&~(1<<NETLINK_DB)))
-			preferred_family = AF_NETLINK;
-	}
-
-	if (preferred_family != AF_UNSPEC) {
-		int mask2;
-		if (preferred_family == AF_INET ||
-		    preferred_family == AF_INET6) {
-			mask2= current_filter.dbs;
-		} else if (preferred_family == AF_PACKET) {
-			mask2 = PACKET_DBM;
-		} else if (preferred_family == AF_UNIX) {
-			mask2 = UNIX_DBM;
-		} else if (preferred_family == AF_NETLINK) {
-			mask2 = (1<<NETLINK_DB);
-		} else {
-			mask2 = 0;
-		}
-
-		if (do_default)
-			current_filter.dbs = mask2;
-		else
-			current_filter.dbs &= mask2;
-		current_filter.families = (1<<preferred_family);
-	} else {
-		if (!do_default)
-			current_filter.families = ~0;
-		else
-			current_filter.families = default_filter.families;
-	}
-	if (current_filter.dbs == 0) {
-		fprintf(stderr, "ss: no socket tables to show with such filter.\n");
-		exit(0);
-	}
-	if (current_filter.families == 0) {
-		fprintf(stderr, "ss: no families to show with such filter.\n");
-		exit(0);
-	}
-
-	if (resolve_services && resolve_hosts &&
-	    (current_filter.dbs&(UNIX_DBM|(1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB))))
-		init_service_resolver();
-
 	/* Now parse filter... */
 	if (argc == 0 && filter_fp) {
 		if (ssfilter_parse(&current_filter.f, 0, NULL, filter_fp))
@@ -3433,15 +3508,15 @@ int main(int argc, char *argv[])
 		if (strcmp(*argv, "state") == 0) {
 			NEXT_ARG();
 			if (!saw_states)
-				current_filter.states = 0;
-			current_filter.states |= scan_state(*argv);
+				state_filter = 0;
+			state_filter |= scan_state(*argv);
 			saw_states = 1;
 		} else if (strcmp(*argv, "exclude") == 0 ||
 			   strcmp(*argv, "excl") == 0) {
 			NEXT_ARG();
 			if (!saw_states)
-				current_filter.states = SS_ALL;
-			current_filter.states &= ~scan_state(*argv);
+				state_filter = SS_ALL;
+			state_filter &= ~scan_state(*argv);
 			saw_states = 1;
 		} else {
 			if (ssfilter_parse(&current_filter.f, argc, argv, filter_fp))
@@ -3451,6 +3526,27 @@ int main(int argc, char *argv[])
 		argc--; argv++;
 	}
 
+	if (do_default) {
+		state_filter = state_filter ? state_filter : SS_CONN;
+		filter_default_dbs(&current_filter);
+		filter_merge(&current_filter, &current_filter, state_filter);
+	} else {
+		filter_merge(&current_filter, &dbs_filter, state_filter);
+	}
+
+	if (resolve_services && resolve_hosts &&
+	    (current_filter.dbs&(UNIX_DBM|(1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB))))
+		init_service_resolver();
+
+
+	if (current_filter.dbs == 0) {
+		fprintf(stderr, "ss: no socket tables to show with such filter.\n");
+		exit(0);
+	}
+	if (current_filter.families == 0) {
+		fprintf(stderr, "ss: no families to show with such filter.\n");
+		exit(0);
+	}
 	if (current_filter.states == 0) {
 		fprintf(stderr, "ss: no socket states to show with such filter.\n");
 		exit(0);
-- 
2.1.3

^ permalink raw reply related

* [PATCH iproute2 v2 2/3] ss: Unify packet stats output from netlink and proc
From: Vadim Kochan @ 2015-01-04 17:20 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1420392055-4754-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Refactored to use one func for output packet stats info
from both /proc and netlink.

Added possibility to get packet stats info from /proc
by setting environment variable PROC_ROOT or PROC_NET_PACKET.

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 215 +++++++++++++++++++++++++++++---------------------------------
 1 file changed, 100 insertions(+), 115 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 4dde080..20d3f75 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -2536,70 +2536,103 @@ static int unix_show(struct filter *f)
 	return 0;
 }
 
-static int packet_show_sock(const struct sockaddr_nl *addr,
-		struct nlmsghdr *nlh, void *arg)
-{
-	struct packet_diag_msg *r = NLMSG_DATA(nlh);
-	struct rtattr *tb[PACKET_DIAG_MAX+1];
-	__u32 rq;
+struct pktstat {
+	int type;
+	int prot;
+	int iface;
+	int state;
+	int rq;
+	int uid;
+	int ino;
+};
 
-	parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr*)(r+1),
-		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
+static int packet_stats_print(struct pktstat *s, const struct filter *f)
+{
+	char *buf = NULL;
 
-	/* use /proc/net/packet if all info are not available */
-	if (!tb[PACKET_DIAG_MEMINFO])
-		return -1;
+	if (f->f) {
+		struct tcpstat tst;
+		tst.local.family = AF_PACKET;
+		tst.remote.family = AF_PACKET;
+		tst.rport = 0;
+		tst.lport = s->iface;
+		tst.local.data[0] = s->prot;
+		tst.remote.data[0] = 0;
+		if (run_ssfilter(f->f, &tst) == 0)
+			return 1;
+	}
 
 	if (netid_width)
 		printf("%-*s ", netid_width,
-				r->pdiag_type == SOCK_RAW ? "p_raw" : "p_dgr");
+				s->type == SOCK_RAW ? "p_raw" : "p_dgr");
 	if (state_width)
 		printf("%-*s ", state_width, "UNCONN");
 
-	if (tb[PACKET_DIAG_MEMINFO]) {
-		__u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]);
-
-		rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
-	} else
-		rq = 0;
-	printf("%-6d %-6d ", rq, 0);
-
-	if (r->pdiag_num == 3) {
+	printf("%-6d %-6d ", s->rq, 0);
+	if (s->prot == 3) {
 		printf("%*s:", addr_width, "*");
 	} else {
-		char tb2[16];
+		char tb[16];
 		printf("%*s:", addr_width,
-		       ll_proto_n2a(htons(r->pdiag_num), tb2, sizeof(tb2)));
+				ll_proto_n2a(htons(s->prot), tb, sizeof(tb)));
 	}
-	if (tb[PACKET_DIAG_INFO]) {
-		struct packet_diag_info *pinfo = RTA_DATA(tb[PACKET_DIAG_INFO]);
-
-		if (pinfo->pdi_index == 0)
-			printf("%-*s ", serv_width, "*");
-		else
-			printf("%-*s ", serv_width, xll_index_to_name(pinfo->pdi_index));
-	} else
+	if (s->iface == 0) {
 		printf("%-*s ", serv_width, "*");
+	} else {
+		printf("%-*s ", serv_width, xll_index_to_name(s->iface));
+	}
 
-	printf("%*s*%-*s",
-	       addr_width, "", serv_width, "");
-
-	char *buf = NULL;
+	printf("%*s*%-*s", addr_width, "", serv_width, "");
 
 	if (show_proc_ctx || show_sock_ctx) {
-		if (find_entry(r->pdiag_ino, &buf,
-				(show_proc_ctx & show_sock_ctx) ?
-				PROC_SOCK_CTX : PROC_CTX) > 0) {
+		if (find_entry(s->ino, &buf,
+					(show_proc_ctx & show_sock_ctx) ?
+					PROC_SOCK_CTX : PROC_CTX) > 0) {
 			printf(" users:(%s)", buf);
 			free(buf);
 		}
 	} else if (show_users) {
-		if (find_entry(r->pdiag_ino, &buf, USERS) > 0) {
+		if (find_entry(s->ino, &buf, USERS) > 0) {
 			printf(" users:(%s)", buf);
 			free(buf);
 		}
 	}
 
+	return 0;
+}
+
+static int packet_show_sock(const struct sockaddr_nl *addr,
+		struct nlmsghdr *nlh, void *arg)
+{
+	const struct filter *f = arg;
+	struct packet_diag_msg *r = NLMSG_DATA(nlh);
+	struct rtattr *tb[PACKET_DIAG_MAX+1];
+	struct pktstat stat = {};
+
+	parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr*)(r+1),
+		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
+
+	/* use /proc/net/packet if all info are not available */
+	if (!tb[PACKET_DIAG_MEMINFO])
+		return -1;
+
+	stat.type = r->pdiag_type;
+	stat.prot = r->pdiag_num;
+	stat.ino = r->pdiag_ino;
+
+	if (tb[PACKET_DIAG_MEMINFO]) {
+		__u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]);
+		stat.rq = skmeminfo[SK_MEMINFO_RMEM_ALLOC];
+	}
+
+	if (tb[PACKET_DIAG_INFO]) {
+		struct packet_diag_info *pinfo = RTA_DATA(tb[PACKET_DIAG_INFO]);
+		stat.iface = pinfo->pdi_index;
+	}
+
+	if (packet_stats_print(&stat, f))
+		return 0;
+
 	if (show_details) {
 		__u32 uid = 0;
 
@@ -2640,94 +2673,46 @@ static int packet_show_netlink(struct filter *f)
 	return handle_netlink_request(f, &req.nlh, sizeof(req), packet_show_sock);
 }
 
+static int packet_show_line(char *buf, const struct filter *f, int fam)
+{
+	unsigned long long sk;
+	struct pktstat stat = {};
+
+	sscanf(buf, "%llx %*d %d %x %d %d %u %u %u",
+			&sk,
+			&stat.type, &stat.prot, &stat.iface, &stat.state,
+			&stat.rq, &stat.uid, &stat.ino);
+
+	if (stat.type == SOCK_RAW && !(f->dbs&(1<<PACKET_R_DB)))
+		return 0;
+	if (stat.type == SOCK_DGRAM && !(f->dbs&(1<<PACKET_DG_DB)))
+		return 0;
+
+	if (packet_stats_print(&stat, f))
+		return 0;
+
+	if (show_details) {
+		printf(" ino=%u uid=%u sk=%llx", stat.ino, stat.uid, sk);
+	}
+	printf("\n");
+	return 0;
+}
 
 static int packet_show(struct filter *f)
 {
 	FILE *fp;
-	char buf[256];
-	int type;
-	int prot;
-	int iface;
-	int state;
-	int rq;
-	int uid;
-	int ino;
-	unsigned long long sk;
 
 	if (preferred_family != AF_PACKET && !(f->states & (1 << SS_CLOSE)))
 		return 0;
 
-	if (packet_show_netlink(f) == 0)
+	if (!getenv("PROC_NET_PACKET") && !getenv("PROC_ROOT") &&
+			packet_show_netlink(f) == 0)
 		return 0;
 
 	if ((fp = net_packet_open()) == NULL)
 		return -1;
-	fgets(buf, sizeof(buf)-1, fp);
-
-	while (fgets(buf, sizeof(buf)-1, fp)) {
-		sscanf(buf, "%llx %*d %d %x %d %d %u %u %u",
-		       &sk,
-		       &type, &prot, &iface, &state,
-		       &rq, &uid, &ino);
-
-		if (type == SOCK_RAW && !(f->dbs&(1<<PACKET_R_DB)))
-			continue;
-		if (type == SOCK_DGRAM && !(f->dbs&(1<<PACKET_DG_DB)))
-			continue;
-		if (f->f) {
-			struct tcpstat tst;
-			tst.local.family = AF_PACKET;
-			tst.remote.family = AF_PACKET;
-			tst.rport = 0;
-			tst.lport = iface;
-			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,
-			       type == SOCK_RAW ? "p_raw" : "p_dgr");
-		if (state_width)
-			printf("%-*s ", state_width, "UNCONN");
-		printf("%-6d %-6d ", rq, 0);
-		if (prot == 3) {
-			printf("%*s:", addr_width, "*");
-		} else {
-			char tb[16];
-			printf("%*s:", addr_width,
-			       ll_proto_n2a(htons(prot), tb, sizeof(tb)));
-		}
-		if (iface == 0) {
-			printf("%-*s ", serv_width, "*");
-		} else {
-			printf("%-*s ", serv_width, xll_index_to_name(iface));
-		}
-		printf("%*s*%-*s",
-		       addr_width, "", serv_width, "");
-
-		char *buf = NULL;
-
-		if (show_proc_ctx || show_sock_ctx) {
-			if (find_entry(ino, &buf,
-					(show_proc_ctx & show_sock_ctx) ?
-					PROC_SOCK_CTX : PROC_CTX) > 0) {
-				printf(" users:(%s)", buf);
-				free(buf);
-			}
-		} else if (show_users) {
-			if (find_entry(ino, &buf, USERS) > 0) {
-				printf(" users:(%s)", buf);
-				free(buf);
-			}
-		}
-
-		if (show_details) {
-			printf(" ino=%u uid=%u sk=%llx", ino, uid, sk);
-		}
-		printf("\n");
-	}
+	if (generic_record_read(fp, packet_show_line, f, AF_PACKET))
+		return -1;
 
 	return 0;
 }
-- 
2.1.3

^ permalink raw reply related

* [PATCH iproute2 v2 1/3] ss: Unify unix stats output from netlink and proc
From: Vadim Kochan @ 2015-01-04 17:20 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1420392055-4754-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Refactored to use one func for output unix stats info
from both /proc and netlink.

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 99 ++++++++++++++++++++++++---------------------------------------
 1 file changed, 37 insertions(+), 62 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index f0c7b34..4dde080 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -25,6 +25,7 @@
 #include <dirent.h>
 #include <fnmatch.h>
 #include <getopt.h>
+#include <stdbool.h>
 
 #include "utils.h"
 #include "rt_names.h"
@@ -2234,6 +2235,7 @@ struct unixstat
 	struct unixstat *next;
 	int ino;
 	int peer;
+	char *peer_name;
 	int rq;
 	int wq;
 	int state;
@@ -2279,7 +2281,18 @@ static const char *unix_netid_name(int type)
 	return netid;
 }
 
-static void unix_list_print(struct unixstat *list, struct filter *f)
+static bool unix_type_skip(struct unixstat *s, struct filter *f)
+{
+	if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
+		return true;
+	if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
+		return true;
+	if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
+		return true;
+	return false;
+}
+
+static void unix_stats_print(struct unixstat *list, struct filter *f)
 {
 	struct unixstat *s;
 	char *peer;
@@ -2287,15 +2300,14 @@ static void unix_list_print(struct unixstat *list, struct filter *f)
 	for (s = list; s; s = s->next) {
 		if (!(f->states & (1<<s->state)))
 			continue;
-		if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
-			continue;
-		if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
-			continue;
-		if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
+		if (unix_type_skip(s, f))
 			continue;
 
 		peer = "*";
-		if (s->peer) {
+		if (s->peer_name)
+			peer = s->peer_name;
+
+		if (s->peer && !s->peer_name) {
 			struct unixstat *p;
 			for (p = list; p; p = p->next) {
 				if (s->peer == p->ino)
@@ -2356,36 +2368,23 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 	struct unix_diag_msg *r = NLMSG_DATA(nlh);
 	struct rtattr *tb[UNIX_DIAG_MAX+1];
 	char name[128];
-	int peer_ino;
-	__u32 rqlen, wqlen;
+	struct unixstat stat = { .name = "*" , .peer_name = "*" };
 
 	parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
 		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
-	if (r->udiag_type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
-		return 0;
-	if (r->udiag_type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
-		return 0;
-	if (r->udiag_type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
-		return 0;
+	stat.type  = r->udiag_type;
+	stat.state = r->udiag_state;
+	stat.ino   = r->udiag_ino;
 
-	if (netid_width)
-		printf("%-*s ", netid_width,
-		       unix_netid_name(r->udiag_type));
-	if (state_width)
-		printf("%-*s ", state_width, sstate_name[r->udiag_state]);
+	if (unix_type_skip(&stat, f))
+		return 0;
 
 	if (tb[UNIX_DIAG_RQLEN]) {
 		struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
-		rqlen = rql->udiag_rqueue;
-		wqlen = rql->udiag_wqueue;
-	} else {
-		rqlen = 0;
-		wqlen = 0;
+		stat.rq = rql->udiag_rqueue;
+		stat.wq = rql->udiag_wqueue;
 	}
-
-	printf("%-6u %-6u ", rqlen, wqlen);
-
 	if (tb[UNIX_DIAG_NAME]) {
 		int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
 
@@ -2393,41 +2392,17 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 		name[len] = '\0';
 		if (name[0] == '\0')
 			name[0] = '@';
-	} else
-		sprintf(name, "*");
-
+		stat.name = &name[0];
+	}
 	if (tb[UNIX_DIAG_PEER])
-		peer_ino = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
-	else
-		peer_ino = 0;
+		stat.peer = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
 
-	printf("%*s %-*d %*s %-*d",
-			addr_width, name,
-			serv_width, r->udiag_ino,
-			addr_width, "*", /* FIXME */
-			serv_width, peer_ino);
-
-	char *buf = NULL;
-
-	if (show_proc_ctx || show_sock_ctx) {
-		if (find_entry(r->udiag_ino, &buf,
-				(show_proc_ctx & show_sock_ctx) ?
-				PROC_SOCK_CTX : PROC_CTX) > 0) {
-			printf(" users:(%s)", buf);
-			free(buf);
-		}
-	} else if (show_users) {
-		if (find_entry(r->udiag_ino, &buf, USERS) > 0) {
-			printf(" users:(%s)", buf);
-			free(buf);
-		}
-	}
+	unix_stats_print(&stat, f);
 
 	if (show_mem) {
-		printf("\n\t");
+		printf("\t");
 		print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
 	}
-
 	if (show_details) {
 		if (tb[UNIX_DIAG_SHUTDOWN]) {
 			unsigned char mask;
@@ -2435,9 +2410,8 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 			printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
 		}
 	}
-
-	printf("\n");
-
+	if (show_mem || show_details)
+		printf("\n");
 	return 0;
 }
 
@@ -2505,6 +2479,7 @@ static int unix_show(struct filter *f)
 		if (!(u = malloc(sizeof(*u))))
 			break;
 		u->name = NULL;
+		u->peer_name = NULL;
 
 		if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
 			   &u->peer, &u->rq, &u->wq, &flags, &u->type,
@@ -2544,7 +2519,7 @@ static int unix_show(struct filter *f)
 			strcpy(u->name, name);
 		}
 		if (++cnt > MAX_UNIX_REMEMBER) {
-			unix_list_print(list, f);
+			unix_stats_print(list, f);
 			unix_list_free(list);
 			list = NULL;
 			cnt = 0;
@@ -2552,7 +2527,7 @@ static int unix_show(struct filter *f)
 	}
 	fclose(fp);
 	if (list) {
-		unix_list_print(list, f);
+		unix_stats_print(list, f);
 		unix_list_free(list);
 		list = NULL;
 		cnt = 0;
-- 
2.1.3

^ permalink raw reply related

* [PATCH iproute2 v2 0/3] ss: Fix sockets filtering
From: Vadim Kochan @ 2015-01-04 17:20 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan

From: Vadim Kochan <vadim4j@gmail.com>

PLEASE MAKE ADDITIONAL TESTING !!!

v2:
    patch #1
        1) Used bool and true/false

    patch #3:
        1) Added 'const' to 'filter' tables in patch #3
        3) Get rid of default_filter
        4) Changed a little bit merging of filtering options
        5) Now packet and netlink show funcs requires AF and SS_CLOSE to be set
 
This series contains refactoring & fixes related to sockets filtering.

1st 2 patches relates mostly to refactoring as they just
allows to use one func to output UNIX & PACKET socket stats from both Netlink &
/proc.

The last one have a big change which related to the way how filtering options
are combined with each other. This change has also fixes for some filtering
combination options.

I did some basic testing *BUT* I cant guarantee that there is no bugs ...
Here is my some testing list with comparing to the 'master' version:

Some test results with comparing version in PATCH and version from master
-------------------------------------------------------------------------

this   - ss version sending in PATCH
master - ss version in master

Case #1: Show only IPv4 sockets
    $ ss -4

    RESULTS
        this    -  shows only IPv4 sockets with established states     [OK]
        master  -  shows IPv4 and UNIX sockets with established states [FAIL]

Case #2: Show only IPv4 sockets with all states
    $ ss -4 -a

    RESULTS
        this    -  shows only IPv4 sockets with all states [OK]
        master  -  shows ALL sockets kinds with all states [FAIL]

Case #3: Show only IPv4 sockets with listen states (closed or listening)
    $ ss -4 -l

    RESULTS
        this    -  shows only IPv4 sockets with listen states    [OK]
        master  -  shows ALL sockets kinds with LISTENING states [FAIL]

Case #4 Show only IPv4 UDP sockets
    $ ss -4 -u

    RESULTS
        this    -  shows only IPv4 UDP sockets                                 [OK]
        master  -  shows IPv4 UDP sockets but only if state 'closed' specified [FAIL]
    
    In 'this' version it is not needed to set 'closed' state additionally for UDP sockets as it it set
    automatically because we explicitly specified UDP sockets. 

Case #5: Show all UDP sockets
    $ ss -u

    RESULTS
        this    -  shows all UDP sockets for both IPv4/IPv6 protocol families  [OK]
        master  -  shows IPv4 UDP sockets but only if state 'closed' specified [FAIL]

Case #6: Show all UDP sockets for IPv6 only protocol
    $ ss -u -6

    RESULTS
        this    -  shows all IPv6 UDP sockets                                  [OK]
        master  -  shows IPv4 UDP sockets but only if state 'closed' specified [FAIL]


Case #7: Show UNIX sockets with matches "*X11*" as src
    $ ss src unix:*X11*

    RESULTS
        this    -  shows only UNIX sockets with established states with src matches "*X11*" [OK]
        master  -  shows all established UNIX sockets with "RTNETLINK" errors               [FAIL]


Case #8: Show UNIX sockets with matches "*X11*" as src but with LISTENING states only
    $ ss src unix:*X11* -l

    RESULTS
        this    -  shows only UNIX sockets with LISTENING states with src matches "*X11*" [OK]
        master  -  Segmentation error                                                     [FAIL]

Case #9: Show all RAW sockets
    $ ss -w

    RESULTS
        this    - shows all RAW sockets for IPv4/IPv6 families                                  [OK]
        master  - shows all RAW sockets for IPv4/IPv6 families only if state 'closed' specified [FAIL]

Case #10: Show all TCP/UDP sockets
    $ ss -t -u

    RESULTS
        this    - shows all established TCP and unconnected UDP sockets for IPv4/IPv6 protocols. [OK]
        master  - shows only TCP established sockets, shows UDP                                  [FAIL]

Vadim Kochan (3):
  ss: Unify unix stats output from netlink and proc
  ss: Unify packet stats output from netlink and proc
  ss: Filtering logic changing, with fixes

 misc/ss.c | 628 ++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 346 insertions(+), 282 deletions(-)

-- 
2.1.3

^ permalink raw reply

* Re: [PATCH] net: wireless: rt2x00: use helper to check capability/requirement
From: Stanislaw Gruszka @ 2015-01-04 15:57 UTC (permalink / raw)
  To: Fred Chou
  Cc: helmut.schaa, kvalo, linux-wireless, users, netdev, linux-kernel
In-Reply-To: <1419581958-5927-1-git-send-email-fred.chou.nd@gmail.com>

On Fri, Dec 26, 2014 at 04:19:18PM +0800, Fred Chou wrote:
> From: Fred Chou <fred.chou.nd@gmail.com>
> 
> Use rt2x00_has_cap_flag macro to check rt2x00dev->cap_flags. 
> 
> Signed-off-by: Fred Chou <fred.chou.nd@gmail.com>

Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>

^ permalink raw reply

* [PATCH] bluetooth: Remove unused function
From: Rickard Strandqvist @ 2015-01-04 15:55 UTC (permalink / raw)
  To: Marcel Holtmann, Gustavo Padovan
  Cc: Rickard Strandqvist, Johan Hedberg, David S. Miller,
	linux-bluetooth, netdev, linux-kernel

Remove the function hci_conn_change_link_key() that is not used anywhere.

This was partially found by using a static code analysis program called cppcheck.

Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
 include/net/bluetooth/hci_core.h |    1 -
 net/bluetooth/hci_conn.c         |   15 ---------------
 2 files changed, 16 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 37ff1ae..a922163 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -728,7 +728,6 @@ int hci_conn_check_link_mode(struct hci_conn *conn);
 int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
 int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,
 		      bool initiator);
-int hci_conn_change_link_key(struct hci_conn *conn);
 int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
 
 void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index b9517bd..1fc18b6 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1075,21 +1075,6 @@ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
 }
 EXPORT_SYMBOL(hci_conn_check_secure);
 
-/* Change link key */
-int hci_conn_change_link_key(struct hci_conn *conn)
-{
-	BT_DBG("hcon %p", conn);
-
-	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
-		struct hci_cp_change_conn_link_key cp;
-		cp.handle = cpu_to_le16(conn->handle);
-		hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
-			     sizeof(cp), &cp);
-	}
-
-	return 0;
-}
-
 /* Switch role */
 int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
 {
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH] wl1251: Remove unused function
From: Rickard Strandqvist @ 2015-01-04 15:43 UTC (permalink / raw)
  To: Kalle Valo, Pavel Machek
  Cc: Rickard Strandqvist, Pali Rohár, David Gnedt, George Spelvin,
	Surendra Patil, linux-wireless, netdev, linux-kernel

Remove the function wl1251_cmd_read_memory() that is not used anywhere.

This was partially found by using a static code analysis program called cppcheck.

Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
 drivers/net/wireless/ti/wl1251/cmd.c |   40 ----------------------------------
 drivers/net/wireless/ti/wl1251/cmd.h |    2 --
 2 files changed, 42 deletions(-)

diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c
index ede31f0..26f4d74 100644
--- a/drivers/net/wireless/ti/wl1251/cmd.c
+++ b/drivers/net/wireless/ti/wl1251/cmd.c
@@ -346,46 +346,6 @@ out:
 	return ret;
 }
 
-int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
-			   size_t len)
-{
-	struct cmd_read_write_memory *cmd;
-	int ret = 0;
-
-	wl1251_debug(DEBUG_CMD, "cmd read memory");
-
-	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-	if (!cmd) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	WARN_ON(len > MAX_READ_SIZE);
-	len = min_t(size_t, len, MAX_READ_SIZE);
-
-	cmd->addr = addr;
-	cmd->size = len;
-
-	ret = wl1251_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
-	if (ret < 0) {
-		wl1251_error("read memory command failed: %d", ret);
-		goto out;
-	}
-
-	/* the read command got in, we can now read the answer */
-	wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
-
-	if (cmd->header.status != CMD_STATUS_SUCCESS)
-		wl1251_error("error in read command result: %d",
-			     cmd->header.status);
-
-	memcpy(answer, cmd->value, len);
-
-out:
-	kfree(cmd);
-	return ret;
-}
-
 int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
 			    void *buf, size_t buf_len)
 {
diff --git a/drivers/net/wireless/ti/wl1251/cmd.h b/drivers/net/wireless/ti/wl1251/cmd.h
index d824ff9..5f35430 100644
--- a/drivers/net/wireless/ti/wl1251/cmd.h
+++ b/drivers/net/wireless/ti/wl1251/cmd.h
@@ -40,8 +40,6 @@ int wl1251_cmd_data_path_tx(struct wl1251 *wl, u8 channel, bool enable);
 int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
 		    u16 beacon_interval, u8 dtim_interval);
 int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode);
-int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
-			   size_t len);
 int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
 			    void *buf, size_t buf_len);
 int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH] brcm80211: brcmsmac: dma: Remove some unused functions
From: Rickard Strandqvist @ 2015-01-04 12:43 UTC (permalink / raw)
  To: Larry Finger
  Cc: Brett Rudley, Arend van Spriel, Hante Meuleman, Kalle Valo,
	Fabian Frederick,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	brcm80211-dev-list-dY08KVG/lbpWk0Htik3J/w, Network Development,
	Linux Kernel Mailing List
In-Reply-To: <54A8DBF4.4050202-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>

2015-01-04 7:21 GMT+01:00 Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>:
> On 01/03/2015 06:47 PM, Rickard Strandqvist wrote:
>>
>> Removes some functions that are not used anywhere:
>> dma_txflush() dma_txsuspended()
>>
>> This was partially found by using a static code analysis program called
>> cppcheck.
>>
>> Signed-off-by: Rickard Strandqvist
>> <rickard_strandqvist-IW2WV5XWFqGZkjO+N0TKoMugMpMbD5Xr@public.gmane.org>
>> ---
>>   drivers/net/wireless/brcm80211/brcmsmac/dma.c |   19 -------------------
>>   drivers/net/wireless/brcm80211/brcmsmac/dma.h |    2 --
>>   2 files changed, 21 deletions(-)
>
>
> Just because file dma.c is involved, it does not need to be, nor should it
> be in the subject line. You could specify the driver names in the file tree
> after wireless. In this instance, one possible subject would be "brcm80211:
> brcmsmac: Remove some unused functions". On the other hand, if you look at
> "git log" to see past patches, the driver maintainers even leave off the
> brcm80211 part, thus to match them, the subject should be "brcmsmac: Remove
> some unused functions".
>
> As was suggested earlier, you need to look at the precedents. Keeping a
> uniform method of patch naming helps when looking for patches in the git
> log.
>
> Larry
>


Hi Larry

As I hope you can see I have made some changes regarding the
subject-line. Thought it was an advantage to be able to see which file
I actually removed something from.
There seems to be a big focus on getting right on subject-line right
in recent weeks.

I wonder why there is a script that takes a file name, and respond
with an appropriate subject line?

But ok, I change my script accordingly. Should I submit the patch again?


Kind regards
Rickard Strandqvist
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [net-next PATCH v1 01/11] net: flow_table: create interface for hw match/action tables
From: Thomas Graf @ 2015-01-04 11:12 UTC (permalink / raw)
  To: John Fastabend; +Cc: sfeldma, jiri, jhs, simon.horman, netdev, davem, andy
In-Reply-To: <20141231194544.31070.30335.stgit@nitbit.x32>

On 12/31/14 at 11:45am, John Fastabend wrote:

Impressive work John, some minor nits below. In general this looks
great. How large could tables grow? Any risk one of the nested
attribtues could exceed 16K in size because of a very large parse
graph? Not a problem if we account for it and allow for jumbo
attributes.

> +
> +/**
> + * @struct net_flow_header
> + * @brief defines a match (header/field) an endpoint can use
> + *
> + * @uid unique identifier for header
> + * @field_sz number of fields are in the set
> + * @fields the set of fields in the net_flow_header

FWIW, name is not documented.

> + */
> +struct net_flow_header {
> +	char name[NET_FLOW_NAMSIZ];
> +	int uid;
> +	int field_sz;
> +	struct net_flow_field *fields;
> +};
> +
> +
> +/**
> + * @struct net_flow_table
> + * @brief define flow table with supported match/actions
> + *
> + * @uid unique identifier for table
> + * @source uid of parent table
> + * @size max number of entries for table or -1 for unbounded
> + * @matches null terminated set of supported match types given by match uid
> + * @actions null terminated set of supported action types given by action uid
> + * @flows set of flows

name not documented, flows seems to be leftover

> + */
> +struct net_flow_table {
> +	char name[NET_FLOW_NAMSIZ];
> +	int uid;
> +	int source;
> +	int size;
> +	struct net_flow_field_ref *matches;
> +	int *actions;
> +};
> +
> +/* net_flow_hdr_node: node in a header graph of header fields.
> + *
> + * @uid : unique id of the graph node
> + * @flwo_header_ref : identify the hdrs that can handled by this node
> + * @net_flow_jump_table : give a case jump statement
> + */

needs more work too ;)

> +struct net_flow_hdr_node {
> +	char name[NET_FLOW_NAMSIZ];
> +	int uid;
> +	int *hdrs;
> +	struct net_flow_jump_table *jump;
> +};
> + */
> +
> +/* Netlink description:
> + *
> + * Table definition used to describe running tables. The following
> + * describes the netlink message returned from a flow API messages.
> + *
> + * Flow table definitions used to define tables.
> + *
> + * [NET_FLOW_TABLE_IDENTIFIER_TYPE]
> + * [NET_FLOW_TABLE_IDENTIFIER]
> + * [NET_FLOW_TABLE_TABLES]
> + *     [NET_FLOW_TABLE]
> + *       [NET_FLOW_TABLE_ATTR_NAME]
> + *       [NET_FLOW_TABLE_ATTR_UID]
> + *       [NET_FLOW_TABLE_ATTR_SOURCE]
> + *       [NET_FLOW_TABLE_ATTR_SIZE]
> + *	 [NET_FLOW_TABLE_ATTR_MATCHES]

The tabs and spaces mix make the indentation wrong in the patch, it
looks correct unquoted though but consistency would make this perfect.

> +#ifndef _UAPI_LINUX_IF_FLOW
> +#define _UAPI_LINUX_IF_FLOW
> +
> +#include <linux/types.h>
> +#include <linux/netlink.h>
> +#include <linux/if.h>
> +
> +#define NET_FLOW_NAMSIZ 80

Did you consider allocating the memory for names? I don't have a grasp
for the typical number of net_flow_* instances in memory yet.

> +/**
> + * @struct net_flow_field_ref
> + * @brief uniquely identify field as header:field tuple
> + */
> +struct net_flow_field_ref {
> +	int instance;
> +	int header;
> +	int field;
> +	int mask_type;
> +	int type;
> +	union {	/* Are these all the required data types */
> +		__u8 value_u8;
> +		__u16 value_u16;
> +		__u32 value_u32;
> +		__u64 value_u64;
> +	};
> +	union {	/* Are these all the required data types */
> +		__u8 mask_u8;
> +		__u16 mask_u16;
> +		__u32 mask_u32;
> +		__u64 mask_u64;
> +	};
> +};

Does it make sense to write this as follows?

union {
        struct {
                __u8 value_u8;
                __u8 mask_u8;
        };
        struct {
                __u16 value_u16;
                __u16 mask_u16;
        };
        ...
};

> +#define NET_FLOW_TABLE_EGRESS_ROOT 1
> +#define	NET_FLOW_TABLE_INGRESS_ROOT 2

Tab/space mix.

> +struct sk_buff *net_flow_build_actions_msg(struct net_flow_action **a,
> +					   struct net_device *dev,
> +					   u32 portid, int seq, u8 cmd)
> +{
> +	struct genlmsghdr *hdr;
> +	struct sk_buff *skb;
> +	int err = -ENOBUFS;
> +
> +	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);

genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);

> +static int net_flow_put_table(struct net_device *dev,
> +			      struct sk_buff *skb,
> +			      struct net_flow_table *t)
> +{
> +	struct nlattr *matches, *actions;
> +	int i;
> +
> +	if (nla_put_string(skb, NET_FLOW_TABLE_ATTR_NAME, t->name) ||
> +	    nla_put_u32(skb, NET_FLOW_TABLE_ATTR_UID, t->uid) ||
> +	    nla_put_u32(skb, NET_FLOW_TABLE_ATTR_SOURCE, t->source) ||
> +	    nla_put_u32(skb, NET_FLOW_TABLE_ATTR_SIZE, t->size))
> +		return -EMSGSIZE;
> +
> +	matches = nla_nest_start(skb, NET_FLOW_TABLE_ATTR_MATCHES);
> +	if (!matches)
> +		return -EMSGSIZE;
> +
> +	for (i = 0; t->matches[i].instance; i++)
> +		nla_put(skb, NET_FLOW_FIELD_REF,
> +			sizeof(struct net_flow_field_ref),
> +			&t->matches[i]);

Unhandled nla_put() error


> +static struct sk_buff *net_flow_build_tables_msg(struct net_flow_table **t,
> +						 struct net_device *dev,
> +						 u32 portid, int seq, u8 cmd)
> +{
> +	struct genlmsghdr *hdr;
> +	struct sk_buff *skb;
> +	int err = -ENOBUFS;
> +
> +	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);

genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);

> +static int net_flow_put_headers(struct sk_buff *skb,
> +				struct net_flow_header **headers)
> +{
> +	struct nlattr *nest, *hdr, *fields;
> +	struct net_flow_header *h;
> +	int i, err;
> +
> +	nest = nla_nest_start(skb, NET_FLOW_HEADERS);
> +	if (!nest)
> +		return -EMSGSIZE;
> +
> +	for (i = 0; headers[i]->uid; i++) {
> +		err = -EMSGSIZE;
> +		h = headers[i];
> +
> +		hdr = nla_nest_start(skb, NET_FLOW_HEADER);
> +		if (!hdr)
> +			goto hdr_put_failure;
> +
> +		if (nla_put_string(skb, NET_FLOW_HEADER_ATTR_NAME, h->name) ||
> +		    nla_put_u32(skb, NET_FLOW_HEADER_ATTR_UID, h->uid))
> +			goto attr_put_failure;
> +
> +		fields = nla_nest_start(skb, NET_FLOW_HEADER_ATTR_FIELDS);
> +		if (!fields)
> +			goto attr_put_failure;

You can jump to hdr_put_failure right away and get rid of the
attr_put_failure target as you cancel that nest anyway. You can apply 
this comment to several other places as well if you want.

> +
> +		err = net_flow_put_fields(skb, h);
> +		if (err)
> +			goto fields_put_failure;
> +
> +		nla_nest_end(skb, fields);
> +
> +		nla_nest_end(skb, hdr);
> +	}
> +	nla_nest_end(skb, nest);
> +
> +	return 0;
> +fields_put_failure:
> +	nla_nest_cancel(skb, fields);
> +attr_put_failure:
> +	nla_nest_cancel(skb, hdr);
> +hdr_put_failure:
> +	nla_nest_cancel(skb, nest);
> +	return err;
> +}
> +
> +static struct sk_buff *net_flow_build_headers_msg(struct net_flow_header **h,
> +						  struct net_device *dev,
> +						  u32 portid, int seq, u8 cmd)
> +{
> +	struct genlmsghdr *hdr;
> +	struct sk_buff *skb;
> +	int err = -ENOBUFS;
> +
> +	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
>
genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);

> +static
> +struct sk_buff *net_flow_build_graph_msg(struct net_flow_tbl_node **g,
> +					 struct net_device *dev,
> +					 u32 portid, int seq, u8 cmd)
> +{
> +	struct genlmsghdr *hdr;
> +	struct sk_buff *skb;
> +	int err = -ENOBUFS;
> +
> +	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
>
genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);

^ permalink raw reply

* [PATCH] net/fsl: Add mEMAC MDIO support to XGMAC MDIO
From: shh.xie @ 2015-01-04  9:36 UTC (permalink / raw)
  To: netdev, davem; +Cc: Andy Fleming, Shaohui Xie

From: Andy Fleming <afleming@gmail.com>

The Freescale mEMAC supports operating at 10/100/1000/10G, and
its associated MDIO controller is likewise capable of operating
both Clause 22 and Clause 45 MDIO buses. It is nearly identical
to the MDIO controller on the XGMAC, so we just modify that
driver.

Portions of this driver developed by:

Sandeep Singh <sandeep@freescale.com>
Roy Zang <tie-fei.zang@freescale.com>

Signed-off-by: Andy Fleming <afleming@gmail.com>
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
 drivers/net/ethernet/freescale/Kconfig      |  3 +-
 drivers/net/ethernet/freescale/xgmac_mdio.c | 64 ++++++++++++++++++++++++-----
 2 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index 2703083..ba84c4a 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -69,7 +69,8 @@ config FSL_XGMAC_MDIO
 	select PHYLIB
 	select OF_MDIO
 	---help---
-	  This driver supports the MDIO bus on the Fman 10G Ethernet MACs.
+	  This driver supports the MDIO bus on the Fman 10G Ethernet MACs, and
+	  on the FMan mEMAC (which supports both Clauses 22 and 45)
 
 config UCC_GETH
 	tristate "Freescale QE Gigabit Ethernet"
diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
index a352445..e0fc3d1 100644
--- a/drivers/net/ethernet/freescale/xgmac_mdio.c
+++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
@@ -32,6 +32,7 @@ struct tgec_mdio_controller {
 	__be32	mdio_addr;	/* MDIO address */
 } __packed;
 
+#define MDIO_STAT_ENC		BIT(6)
 #define MDIO_STAT_CLKDIV(x)	(((x>>1) & 0xff) << 8)
 #define MDIO_STAT_BSY		(1 << 0)
 #define MDIO_STAT_RD_ER		(1 << 1)
@@ -91,20 +92,40 @@ static int xgmac_wait_until_done(struct device *dev,
 static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
 {
 	struct tgec_mdio_controller __iomem *regs = bus->priv;
-	uint16_t dev_addr = regnum >> 16;
+	uint16_t dev_addr;
+	u32 mdio_ctl, mdio_stat;
 	int ret;
 
-	/* Set the port and dev addr */
-	out_be32(&regs->mdio_ctl,
-		 MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr));
+	mdio_stat = in_be32(&regs->mdio_stat);
+	if (regnum & MII_ADDR_C45) {
+		/* Clause 45 (ie 10G) */
+		dev_addr = (regnum >> 16) & 0x1f;
+		mdio_stat |= MDIO_STAT_ENC;
+	} else {
+		/* Clause 22 (ie 1G) */
+		dev_addr = regnum & 0x1f;
+		mdio_stat &= ~MDIO_STAT_ENC;
+	}
 
-	/* Set the register address */
-	out_be32(&regs->mdio_addr, regnum & 0xffff);
+	out_be32(&regs->mdio_stat, mdio_stat);
 
 	ret = xgmac_wait_until_free(&bus->dev, regs);
 	if (ret)
 		return ret;
 
+	/* Set the port and dev addr */
+	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
+	out_be32(&regs->mdio_ctl, mdio_ctl);
+
+	/* Set the register address */
+	if (regnum & MII_ADDR_C45) {
+		out_be32(&regs->mdio_addr, regnum & 0xffff);
+
+		ret = xgmac_wait_until_free(&bus->dev, regs);
+		if (ret)
+			return ret;
+	}
+
 	/* Write the value to the register */
 	out_be32(&regs->mdio_data, MDIO_DATA(value));
 
@@ -123,21 +144,39 @@ static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 val
 static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
 {
 	struct tgec_mdio_controller __iomem *regs = bus->priv;
-	uint16_t dev_addr = regnum >> 16;
+	uint16_t dev_addr;
+	uint32_t mdio_stat;
 	uint32_t mdio_ctl;
 	uint16_t value;
 	int ret;
 
+	mdio_stat = in_be32(&regs->mdio_stat);
+	if (regnum & MII_ADDR_C45) {
+		dev_addr = (regnum >> 16) & 0x1f;
+		mdio_stat |= MDIO_STAT_ENC;
+	} else {
+		dev_addr = regnum & 0x1f;
+		mdio_stat = ~MDIO_STAT_ENC;
+	}
+
+	out_be32(&regs->mdio_stat, mdio_stat);
+
+	ret = xgmac_wait_until_free(&bus->dev, regs);
+	if (ret)
+		return ret;
+
 	/* Set the Port and Device Addrs */
 	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
 	out_be32(&regs->mdio_ctl, mdio_ctl);
 
 	/* Set the register address */
-	out_be32(&regs->mdio_addr, regnum & 0xffff);
+	if (regnum & MII_ADDR_C45) {
+		out_be32(&regs->mdio_addr, regnum & 0xffff);
 
-	ret = xgmac_wait_until_free(&bus->dev, regs);
-	if (ret)
-		return ret;
+		ret = xgmac_wait_until_free(&bus->dev, regs);
+		if (ret)
+			return ret;
+	}
 
 	/* Initiate the read */
 	out_be32(&regs->mdio_ctl, mdio_ctl | MDIO_CTL_READ);
@@ -224,6 +263,9 @@ static struct of_device_id xgmac_mdio_match[] = {
 	{
 		.compatible = "fsl,fman-xmdio",
 	},
+	{
+		.compatible = "fsl,fman-memac-mdio",
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, xgmac_mdio_match);
-- 
1.8.4.1

^ permalink raw reply related

* Re: [PATCH net-next] rhashtable: fix missing header
From: Thomas Graf @ 2015-01-04  9:57 UTC (permalink / raw)
  To: Ying Xue; +Cc: davem, netdev
In-Reply-To: <54A906CF.7000309@windriver.com>

On 01/04/15 at 05:24pm, Ying Xue wrote:
> On 01/04/2015 05:19 PM, Thomas Graf wrote:
> > On 01/04/15 at 03:25pm, Ying Xue wrote:
> >> Fixup below build error:
> >>
> >> include/linux/rhashtable.h: At top level:
> >> include/linux/rhashtable.h:118:34: error: field ???mutex??? has incomplete type
> > 
> > Just wondering, is this your new code that didn't compile? The code
> > compiled fine for me for the existing users.
> > 
> 
> When I did below patch, I met the build error.

OK, personally I would squash it with that patch then as it's only
needed in combination with the new code.

> http://patchwork.ozlabs.org/patch/425149/
> 
> By the way, please help to review the patch if you have time :)

The convertion looks straight forward although I'm not fully familiar
with the TIPC code. I left a comment with a further optimization idea.

^ permalink raw reply

* Re: [PATCH net-next] tipc: convert tipc reference table to use generic rhashtable
From: Thomas Graf @ 2015-01-04  9:53 UTC (permalink / raw)
  To: Ying Xue
  Cc: netdev, davem, jon.maloy, Paul.Gortmaker, erik.hugne,
	tipc-discussion
In-Reply-To: <1420356862-7523-1-git-send-email-ying.xue@windriver.com>

On 01/04/15 at 03:34pm, Ying Xue wrote:
> As tipc reference table is statically allocated, its memory size
> requested on stack initialization stage is quite big even if the
> maximum port number is just restricted to 8191 currently, however,
> the number already becomes insufficient in practice. But if the
> maximum ports is allowed to its theory value - 2^32, its consumed
> memory size will reach a ridiculously unacceptable value. Apart from
> this, heavy tipc users spend a considerable amount of time in
> tipc_sk_get() due to the read-lock on ref_table_lock.
> 
> If tipc reference table is converted with generic rhashtable, above
> mentioned both disadvantages would be resolved respectively: making
> use of the new resizable hash table can avoid locking on the lookup;
> smaller memory size is required at initial stage, for example, 256
> hash bucket slots are requested at the beginning phase instead of
> allocating the entire 8191 slots in old mode. The hash table will
> grow if entries exceeds 75% of table size up to a total table size
> of 1M, and it will automatically shrink if usage falls below 30%,
> but the minimum table size is allowed down to 256.
> 
> Also converts ref_table_lock to a separate mutex to protect hash table
> mutations on write side. Lastly defers the release of the socket
> reference using call_rcu() to allow using an RCU read-side protected
> call to rhashtable_lookup().

If I read the code correctly, then the only reason for the mutex
to exist is to protect the quest of identifying an unused portid
since the insertion is protected by per bucket locks now.

As a further optimization, you could add a new atomic function
rhashtable_lookup_and_insert() which holds the per bucket lock during
lookup and use that instead. This would allow you to get rid of the
mutex alltogether.

^ permalink raw reply

* Re: [PATCH net-next] rhashtable: fix missing header
From: Ying Xue @ 2015-01-04  9:24 UTC (permalink / raw)
  To: Thomas Graf; +Cc: davem, netdev
In-Reply-To: <20150104091908.GA15305@casper.infradead.org>

On 01/04/2015 05:19 PM, Thomas Graf wrote:
> On 01/04/15 at 03:25pm, Ying Xue wrote:
>> Fixup below build error:
>>
>> include/linux/rhashtable.h: At top level:
>> include/linux/rhashtable.h:118:34: error: field ???mutex??? has incomplete type
> 
> Just wondering, is this your new code that didn't compile? The code
> compiled fine for me for the existing users.
> 

When I did below patch, I met the build error.

http://patchwork.ozlabs.org/patch/425149/

By the way, please help to review the patch if you have time :)

Thanks!

Regards,
Ying

>> Signed-off-by: Ying Xue <ying.xue@windriver.com>
> 
> Fixes: 97defe1e ("rhashtable: Per bucket locks & deferred expansion/shrinking")
> Acked-by: Thomas Graf <tgraf@suug.ch>
> 
> 
> 

^ permalink raw reply

* Re: [PATCH net-next] rhashtable: fix missing header
From: Thomas Graf @ 2015-01-04  9:19 UTC (permalink / raw)
  To: Ying Xue; +Cc: davem, netdev
In-Reply-To: <1420356309-7382-1-git-send-email-ying.xue@windriver.com>

On 01/04/15 at 03:25pm, Ying Xue wrote:
> Fixup below build error:
> 
> include/linux/rhashtable.h: At top level:
> include/linux/rhashtable.h:118:34: error: field ???mutex??? has incomplete type

Just wondering, is this your new code that didn't compile? The code
compiled fine for me for the existing users.

> Signed-off-by: Ying Xue <ying.xue@windriver.com>

Fixes: 97defe1e ("rhashtable: Per bucket locks & deferred expansion/shrinking")
Acked-by: Thomas Graf <tgraf@suug.ch>

^ permalink raw reply

* Re: TCP out of memory - possible bug [3.18.0-rc3] / sched?
From: Markus Trippelsdorf @ 2015-01-04  8:42 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Tomasz Mloduchowski, netdev
In-Reply-To: <1415043704.1005.0.camel@edumazet-glaptop2.roam.corp.google.com>

On 2014.11.03 at 11:41 -0800, Eric Dumazet wrote:
> On Mon, 2014-11-03 at 19:59 +0100, Tomasz Mloduchowski wrote:
> > Hi List,
> > 
> > I hope this is the right place to report a networking issue with
> > 3.18.0-rc2 and 3.18.0-rc3 - under heavy P2P load (tested both
> > rtorrent/libtorrent and bitcoind, so not protocol-specific), the system
> > quickly exhausts tcp_mem limits in a very strange sequence of events.
> > 
> > It might be scheduler or networking subsystem related.
> > 
> > It's 100% reproducible on my system, first observed under 3.18.0-rc2.
> > 
> 
> Sounds a perfect case for a bisection maybe ?

Any news on this issue?

I stumbled across the same problem today with 3.19.0-rc2:

Jan  4 09:23:22 x4 kernel: TCP: out of memory -- consider tuning tcp_mem
Jan  4 09:23:23 x4 kernel: ------------[ cut here ]------------
Jan  4 09:23:23 x4 kernel: WARNING: CPU: 3 PID: 32504 at net/core/stream.c:201 inet_csk_destroy_sock+0x4d/0x100()
Jan  4 09:23:23 x4 kernel: CPU: 3 PID: 32504 Comm: main Not tainted 3.19.0-rc2-00193-g5e0f872c7d7e-dirty #52
Jan  4 09:23:23 x4 kernel: Hardware name: System manufacturer System Product Name/M4A78T-E, BIOS 3503    04/13/2011
Jan  4 09:23:23 x4 kernel: 0000000000000000 ffffffff819b8544 ffffffff81686ffc 0000000000000000
Jan  4 09:23:23 x4 kernel: ffffffff8106b352 ffff88008a623a80 ffff88008a623be8 0000000000000004
Jan  4 09:23:23 x4 kernel: ffff88008a623ae8 ffff88012d3f9240 ffffffff8162fead ffff88008a623a80
Jan  4 09:23:23 x4 kernel: Call Trace:
Jan  4 09:23:23 x4 kernel: [<ffffffff81686ffc>] ? dump_stack+0x40/0x50
Jan  4 09:23:23 x4 kernel: [<ffffffff8106b352>] ? warn_slowpath_common+0x72/0xc0
Jan  4 09:23:23 x4 kernel: [<ffffffff8162fead>] ? inet_csk_destroy_sock+0x4d/0x100
Jan  4 09:23:23 x4 kernel: [<ffffffff81633746>] ? tcp_close+0x226/0x400
Jan  4 09:23:23 x4 kernel: [<ffffffff816582cd>] ? inet_release+0x6d/0x80
Jan  4 09:23:23 x4 kernel: [<ffffffff815cf090>] ? sock_release+0x10/0x80
Jan  4 09:23:23 x4 kernel: [<ffffffff815cf10d>] ? sock_close+0xd/0x20
Jan  4 09:23:23 x4 kernel: [<ffffffff8110eeca>] ? __fput+0xca/0x1e0
Jan  4 09:23:23 x4 kernel: [<ffffffff81081c0f>] ? task_work_run+0xaf/0x100
Jan  4 09:23:23 x4 kernel: [<ffffffff81689734>] ? __schedule+0x254/0x760
Jan  4 09:23:23 x4 kernel: [<ffffffff81039ae1>] ? do_notify_resume+0x61/0xa0
Jan  4 09:23:23 x4 kernel: [<ffffffff8110f33e>] ? fput+0x3e/0x80
Jan  4 09:23:23 x4 kernel: [<ffffffff8168dc18>] ? int_signal+0x12/0x17
Jan  4 09:23:23 x4 kernel: ---[ end trace ccb3dc614f5600b1 ]---
Jan  4 09:23:23 x4 kernel: ------------[ cut here ]------------
Jan  4 09:23:23 x4 kernel: WARNING: CPU: 3 PID: 32504 at net/ipv4/af_inet.c:153 inet_sock_destruct+0x169/0x1e0()
Jan  4 09:23:23 x4 kernel: CPU: 3 PID: 32504 Comm: main Tainted: G        W      3.19.0-rc2-00193-g5e0f872c7d7e-dirty #52
Jan  4 09:23:23 x4 kernel: Hardware name: System manufacturer System Product Name/M4A78T-E, BIOS 3503    04/13/2011
Jan  4 09:23:23 x4 kernel: 0000000000000000 ffffffff819b9876 ffffffff81686ffc 0000000000000000
Jan  4 09:23:23 x4 kernel: ffffffff8106b352 ffff88008a623a80 ffff88008a623bc8 ffff880100104a30
Jan  4 09:23:23 x4 kernel: ffff880216864660 ffff88012d3f9240 ffffffff816591e9 ffff8800d5e2a810
Jan  4 09:23:23 x4 kernel: Call Trace:
Jan  4 09:23:23 x4 kernel: [<ffffffff81686ffc>] ? dump_stack+0x40/0x50
Jan  4 09:23:23 x4 kernel: [<ffffffff8106b352>] ? warn_slowpath_common+0x72/0xc0
Jan  4 09:23:23 x4 kernel: [<ffffffff816591e9>] ? inet_sock_destruct+0x169/0x1e0
Jan  4 09:23:23 x4 kernel: [<ffffffff815d1792>] ? __sk_free+0x12/0xc0
Jan  4 09:23:23 x4 kernel: [<ffffffff816582cd>] ? inet_release+0x6d/0x80
Jan  4 09:23:23 x4 kernel: [<ffffffff815cf090>] ? sock_release+0x10/0x80
Jan  4 09:23:23 x4 kernel: [<ffffffff815cf10d>] ? sock_close+0xd/0x20
Jan  4 09:23:23 x4 kernel: [<ffffffff8110eeca>] ? __fput+0xca/0x1e0
Jan  4 09:23:23 x4 kernel: [<ffffffff81081c0f>] ? task_work_run+0xaf/0x100
Jan  4 09:23:23 x4 kernel: [<ffffffff81689734>] ? __schedule+0x254/0x760
Jan  4 09:23:23 x4 kernel: [<ffffffff81039ae1>] ? do_notify_resume+0x61/0xa0
Jan  4 09:23:23 x4 kernel: [<ffffffff8110f33e>] ? fput+0x3e/0x80
Jan  4 09:23:23 x4 kernel: [<ffffffff8168dc18>] ? int_signal+0x12/0x17
Jan  4 09:23:23 x4 kernel: ---[ end trace ccb3dc614f5600b2 ]---

rtorrent was spinning and the network was unusable until reboot.

-- 
Markus

^ permalink raw reply

* Re: [net-next PATCH v1 04/11] rocker: add pipeline model for rocker switch
From: Or Gerlitz @ 2015-01-04  8:43 UTC (permalink / raw)
  To: John Fastabend
  Cc: Thomas Graf, sfeldma, Jiří Pírko, Jamal Hadi Salim,
	simon.horman, Linux Netdev List, David Miller, Andy Gospodarek
In-Reply-To: <20141231194709.31070.16657.stgit@nitbit.x32>

On Wed, Dec 31, 2014 at 9:47 PM, John Fastabend
<john.fastabend@gmail.com> wrote:
> This adds rocker support for the net_flow_get_* operations. With this
> we can interrogate rocker.
>
> Here we see that for static configurations enabling the get operations
> is simply a matter of defining a pipeline model and returning the
> structures for the core infrastructure to encapsulate into netlink
> messages.

[..]

> diff --git a/drivers/net/ethernet/rocker/rocker_pipeline.h b/drivers/net/ethernet/rocker/rocker_pipeline.h
> new file mode 100644
> index 0000000..9544339
> --- /dev/null
> +++ b/drivers/net/ethernet/rocker/rocker_pipeline.h
> @@ -0,0 +1,673 @@
> +#ifndef _MY_PIPELINE_H_
> +#define _MY_PIPELINE_H_
> +
> +#include <linux/if_flow.h>
> +
> +/* header definition */
> +#define HEADER_ETHERNET_SRC_MAC 1
> +#define HEADER_ETHERNET_DST_MAC 2
> +#define HEADER_ETHERNET_ETHERTYPE 3
> +struct net_flow_field ethernet_fields[3] = {
> +       { .name = "src_mac", .uid = HEADER_ETHERNET_SRC_MAC, .bitwidth = 48},
> +       { .name = "dst_mac", .uid = HEADER_ETHERNET_DST_MAC, .bitwidth = 48},
> +       { .name = "ethertype",
> +         .uid = HEADER_ETHERNET_ETHERTYPE,
> +         .bitwidth = 16},
> +};
> +
> +#define HEADER_ETHERNET 1
> +struct net_flow_header ethernet = {
> +       .name = "ethernet",
> +       .uid = HEADER_ETHERNET,
> +       .field_sz = 3,
> +       .fields = ethernet_fields,
> +};
> +
> +#define HEADER_VLAN_PCP 1
> +#define HEADER_VLAN_CFI 2
> +#define HEADER_VLAN_VID 3
> +#define HEADER_VLAN_ETHERTYPE 4
> +struct net_flow_field vlan_fields[4] = {
> +       { .name = "pcp", .uid = HEADER_VLAN_PCP, .bitwidth = 3,},
> +       { .name = "cfi", .uid = HEADER_VLAN_CFI, .bitwidth = 1,},
> +       { .name = "vid", .uid = HEADER_VLAN_VID, .bitwidth = 12,},
> +       { .name = "ethertype", .uid = HEADER_VLAN_ETHERTYPE, .bitwidth = 16,},
> +};
> +
> +#define HEADER_VLAN 2
> +struct net_flow_header vlan = {
> +       .name = "vlan",
> +       .uid = HEADER_VLAN,
> +       .field_sz = 4,
> +       .fields = vlan_fields,
> +};
> +
> +#define HEADER_IPV4_VERSION 1
> +#define HEADER_IPV4_IHL 2
> +#define HEADER_IPV4_DSCP 3
> +#define HEADER_IPV4_ECN 4
> +#define HEADER_IPV4_LENGTH 5
> +#define HEADER_IPV4_IDENTIFICATION 6
> +#define HEADER_IPV4_FLAGS 7
> +#define HEADER_IPV4_FRAGMENT_OFFSET 8
> +#define HEADER_IPV4_TTL 9
> +#define HEADER_IPV4_PROTOCOL 10
> +#define HEADER_IPV4_CSUM 11
> +#define HEADER_IPV4_SRC_IP 12
> +#define HEADER_IPV4_DST_IP 13
> +#define HEADER_IPV4_OPTIONS 14
> +struct net_flow_field ipv4_fields[14] = {
> +       { .name = "version",
> +         .uid = HEADER_IPV4_VERSION,
> +         .bitwidth = 4,},
> +       { .name = "ihl",
> +         .uid = HEADER_IPV4_IHL,
> +         .bitwidth = 4,},
> +       { .name = "dscp",
> +         .uid = HEADER_IPV4_DSCP,
> +         .bitwidth = 6,},
> +       { .name = "ecn",
> +         .uid = HEADER_IPV4_ECN,
> +         .bitwidth = 2,},
> +       { .name = "length",
> +         .uid = HEADER_IPV4_LENGTH,
> +         .bitwidth = 8,},
> +       { .name = "identification",
> +         .uid = HEADER_IPV4_IDENTIFICATION,
> +         .bitwidth = 8,},
> +       { .name = "flags",
> +         .uid = HEADER_IPV4_FLAGS,
> +         .bitwidth = 3,},
> +       { .name = "fragment_offset",
> +         .uid = HEADER_IPV4_FRAGMENT_OFFSET,
> +         .bitwidth = 13,},
> +       { .name = "ttl",
> +         .uid = HEADER_IPV4_TTL,
> +         .bitwidth = 1,},
> +       { .name = "protocol",
> +         .uid = HEADER_IPV4_PROTOCOL,
> +         .bitwidth = 8,},
> +       { .name = "csum",
> +         .uid = HEADER_IPV4_CSUM,
> +         .bitwidth = 8,},
> +       { .name = "src_ip",
> +         .uid = HEADER_IPV4_SRC_IP,
> +         .bitwidth = 32,},
> +       { .name = "dst_ip",
> +         .uid = HEADER_IPV4_DST_IP,
> +         .bitwidth = 32,},
> +       { .name = "options",
> +         .uid = HEADER_IPV4_OPTIONS,
> +         .bitwidth = -1,},
> +};
> +

John,

Repeating the feedback I provided you f2f in Dusseldorf when the WIP
code was within ixgbe, some/many code pieces in this patch (e.g the
above) are generic and hence should reside not within a low level
driver such as rocker, and also on a separate patch.

Or.

^ permalink raw reply

* Re: [net-next PATCH v1 00/11] A flow API
From: Or Gerlitz @ 2015-01-04  8:30 UTC (permalink / raw)
  To: John Fastabend
  Cc: Thomas Graf, sfeldma, Jiří Pírko, Jamal Hadi Salim,
	simon.horman, Linux Netdev List, David Miller, Andy Gospodarek
In-Reply-To: <20141231194057.31070.5244.stgit@nitbit.x32>

On Wed, Dec 31, 2014 at 9:45 PM, John Fastabend
<john.fastabend@gmail.com> wrote:
> So... I could continue to mull over this and tweak bits and pieces
> here and there but I decided its best to get a wider group of folks
> looking at it and hopefulyl with any luck using it so here it is.
[...]
> I could use some help reviewing
[...]

Hi John,

It would be very helpful to get access to the actual patches, I don't
see them on the netdev patchwork queue, and assume
it's b/c this is still in RFC stage. Cloning your github tree and
looking there, I see some earlier/WIP versions of the code, but it's
not
the submitted patches.

Or.

[1] https://github.com/jrfastab/flow-net-next.git

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox