The passed 'addr' parameter is dereferenced by caller before and in
parse_hostcond() multiple times before this check, so assume it is
always true.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Based on patch by Lehner Florian <dev@der-flo.net>
Adds support for RFC2732 IPv6 address format with brackets.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Use the new helper functions rta_getattr_u* instead of direct
cast of RTA_DATA(). Where RTA_DATA() is a structure, then remove
the unnecessary cast since RTA_DATA() is void *
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
tcpi_rcv_mss and tcpi_advmss tcp info fields were not yet reported
by ss.
While adding GRO support to packetdrill, I found this was useful.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Initialise for loops outside of for loops. GCC flags this as being
out of spec unless C99 or C11 mode is used.
With this change the entire tree appears to compile cleanly with -Wall.
$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
...
$ make
...
ss.c: In function ‘unix_show_sock’:
ss.c:3128:4: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
...
Signed-off-by: Simon Horman <simon.horman@netronome.com>
A struct with only a single field does not make much sense. Besides
that, it was used by print_summary() only.
Signed-off-by: Phil Sutter <phil@nwl.cc>
This function is used only at a single place anymore, so replace the
call to it by it's content, which makes that specific part of
unix_show() consistent with e.g. tcp_show().
Signed-off-by: Phil Sutter <phil@nwl.cc>
Although this complicates the dedicated procfs-based code path in
unix_show() a bit, it's the only sane way to get rid of unix_show_sock()
output diverging from other socket types in that it prints all socket
details in a new line.
As a side effect, it allows to eliminate all procfs specific code in
the same function.
Signed-off-by: Phil Sutter <phil@nwl.cc>
This consolidates identical code in three places. While the function
name is not quite perfect as there is different proc_ctx printing code
in netlink_show_one() as well, I sadly didn't find a more suitable one.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Unix sockets used that field already to hold info about the socket type.
By replicating this approach in all other socket types, we can get rid
of protocol parameter in inet_stats_print() and have sock_state_print()
figure things out by itself.
Signed-off-by: Phil Sutter <phil@nwl.cc>
When dumping UNIX sockets and show_details is active but not show_mem
(ss -xne), the socket details are printed without being prefixed by tab.
Fix this by printing the tab character when either one of '-e' or '-m'
has been specified.
Signed-off-by: Phil Sutter <phil@nwl.cc>
When dumping UDP sockets and show_tcpinfo (-i) is active but not
show_mem (-m), print_tcpinfo() does not output anything leading to an
empty line being printed after every socket. Fix this by skipping the
call to print_tcpinfo() and the previous newline printing in that case.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Dump some new fields added to tcp_info in v4.10: tcpi_busy_time,
tcpi_rwnd_limited, tcpi_sndbuf_limited.
Example output for a flow busy for 110ms but never measurably limited by
receive window or send buffer:
busy:110ms
Example output for a flow usually limited by receive window:
busy:111ms rwnd_limited:101ms(91.0%)
Example output for a flow sometimes limited by send buffer:
busy:50ms sndbuf_limited:10ms(20.0%)
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com>
Dump the new delivery_rate and delivery_rate_app_limited fields that
were added to tcp_info in Linux v4.9.
Example output:
pacing_rate 65.7Mbps delivery_rate 62.9Mbps
And for the application-limited case this looks like:
pacing_rate 1031.1Mbps delivery_rate 87.4Mbps app_limited
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com>
unix, tcp, udp[lite], packet, netlink sockets already support diag
interface for their collection and killing. Implement support
for raw sockets.
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Acked-by: David Ahern <dsa@cumulusnetworks.com>
This makes use of the sctp_diag interface recently added to the kernel.
Joint work with Xin Long who provided the PoC implementation which I
merely polished up a bit.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Abstract unix domain socket may embed null characters,
these should be translated to '@' when printed by ss the
same way the null prefix is currently being translated.
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
tcp->snd_cwd is a u32, but ss treats it like a signed int. This may
results in negative bandwidth calculations.
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Acked-by: Phil Sutter <phil@nwl.cc>
This allows the user to dump sockets with a given mark (via
"fwmark = 0x1234/0x1234" or "fwmark = 12345", etc.) , and to
display the socket marks of dumped sockets.
The relevant kernel commits are: d545caca827b ("net: inet: diag:
expose the socket mark to privileged processes.") and
- a52e95abf772 ("net: diag: allow socket bytecode filters to
match socket marks")
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Dump useful TCP BBR state information from a struct tcp_bbr_info that
was grabbed using the inet_diag API.
We tolerate info that is shorter or longer than expected, in case the
kernel is older or newer than the ss binary. We simply print the
minimum of what is expected from the kernel and what is provided from
the kernel. We use the same trick as that used for struct tcp_info:
when the info from the kernel is shorter than we hoped, we pad the end
with zeroes, and don't print fields if they are zero.
The BBR output looks like:
bbr:(bw:1.2Mbps,mrtt:18.965,pacing_gain:2.88672,cwnd_gain:2.88672)
The motivation here is to be consistent with DCTCP, which looks like:
dctcp(ce_state:23,alpha:23,ab_ecn:23,ab_tot:23)
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com>
This big patch was compiled by vimgrepping for memset calls and changing
to C99 initializer if applicable. One notable exception is the
initialization of union bpf_attr in tc/tc_bpf.c: changing it would break
for older gcc versions (at least <=3.4.6).
Calls to memset for struct rtattr pointer fields for parse_rtattr*()
were just dropped since they are not needed.
The changes here allowed the compiler to discover some unused variables,
so get rid of them, too.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: David Ahern <dsa@cumulusnetworks.com>
Add option to suppress header line. When used the following line
is not shown:
"State Recv-Q Send-Q Local Address:Port Peer Address:Port"
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Support was recently added for device filters. The intent was to allow
the device to be specified by name or index, and using the if%u format
(dev == if5) or the simpler and more intuitive index alone (dev == 5).
The latter case is broken since the index is not saved to the filter
after the strtoul conversion. Further, the tmp variable used for the
conversion shadows another variable used in the function. Fix both.
With this change all 3 variants work as expected:
$ ss -t 'dev == 62'
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 224 10.0.1.3%mgmt:ssh 192.168.0.50:58442
$ ss -t 'dev == mgmt'
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 224 10.0.1.3%mgmt:ssh 192.168.0.50:58442
$ ss -t 'dev == if62'
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 36 10.0.1.3%mgmt:ssh 192.168.0.50:58442
Fixes: 2d29321256 ("ss: Add support to filter on device")
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
This patch was generated by the following semantic patch (a trimmed down
version of what is shipped with Linux sources):
@@
type T;
T[] E;
@@
(
- (sizeof(E)/sizeof(*E))
+ ARRAY_SIZE(E)
|
- (sizeof(E)/sizeof(E[...]))
+ ARRAY_SIZE(E)
|
- (sizeof(E)/sizeof(T))
+ ARRAY_SIZE(E)
)
The only manual adjustment was to include utils.h in misc/nstat.c to make
the macro known there.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Add support for device names in the filter. Example:
root@kenny:~# ss -t 'sport == :22 && dev == red'
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 10.100.1.2%red:ssh 10.100.1.254:47814
ESTAB 0 0 2100:1::2%red:ssh 2100:1::64:49406
Since kernel does not support iface in the filter specifying a
device name means all filtering is done in userspace.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Allow ssfilter_bytecompile to return 0 for filter ops the kernel
does not support. If such an op is in the filter string then all
filtering is done in userspace.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Extract parsing of sockstat and filter from inet_show_sock.
While moving run_ssfilter into callers of inet_show_sock enable
userspace filtering before the kill.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
SK_MEMINFO_DROPS is added in linux-4.7 for TCP, UDP and SCTP
skmem will display the socket drop count using d prefix as in :
$ ss -tm src :22 | more
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 52 10.246.7.151:ssh 172.20.10.101:50759
skmem:(r0,rb8388608,t0,tb8388608,f1792,w2304,o0,bl0,d0)
Signed-off-by: Eric Dumazet <edumazet@google.com>
Kernel sets info->tcpi_min_rtt to ~0U when no RTT sample was ever
taken for the session, thus min_rtt is unknown.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Passing a filter expression and selecting an address family using the
'-f' flag would overwrite the state filter by accident. Therefore
calling e.g. 'ss -nl -f inet '(sport = :22)' would not only print
listening sockets (as requested by '-l' flag) but connected ones, as
well.
Fix this by reusing the formerly ineffective call to filter_states_set()
to restore the state filter as it was before the call to
filter_af_set().
Signed-off-by: Phil Sutter <phil@nwl.cc>
There are only three users which require it to be reentrant, the rest is
fine without. Instead, provide a reentrant format_host_r() for users
which need it.
Signed-off-by: Phil Sutter <phil@nwl.cc>
This patch adds a -K / --kill option to ss that attempts to
forcibly close matching sockets using SOCK_DESTROY.
Because ss typically prints sockets instead of acting on them,
and because the kernel only supports forcibly closing some types
of sockets, the output of -K is as follows:
- If closing the socket succeeds, the socket is printed.
- If the kernel does not support forcibly closing this type of
socket (e.g., if it's a UDP socket, or a TIME_WAIT socket),
the socket is silently skipped.
- If an error occurs (e.g., permission denied), the error is
reported and ss exits.
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
fgets() will read at most size-1 bytes into the buffer and add a
terminating null-char at the end. Therefore it is not necessary to pass
a reduced buffer size when calling it.
This change was generated using the following semantic patch:
@@
identifier buf, fp;
@@
- fgets(buf, sizeof(buf) - 1, fp)
+ fgets(buf, sizeof(buf), fp)
Signed-off-by: Phil Sutter <phil@nwl.cc>
Although not fundamentally necessary to check return codes in these
spots, preventing the warnings will put new ones into focus.
Signed-off-by: Phil Sutter <phil@nwl.cc>
No need to keep static port boundaries global, they are not used
directly. Keeping them local also allows to safely reduce their names to
the minimum. Assign hardcoded fallback values also if fscanf() fails.
Get rid of unnecessary braces around return parameter.
Instead of more or less duplicating is_ephemeral() in run_ssfilter(),
simply call the function instead.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Exit early or continue on error instead of putting conditional into
conditional to make reading the code a bit easier.
Also, the call to memcpy() can be skipped by initialising prog with the
desired prefix.
Signed-off-by: Phil Sutter <phil@nwl.cc>
When getopt_long encounters an option which has not been registered, it
returns '?'. React upon that and call usage() instead of help() so ss
returns with a non-zero exit status.
Signed-off-by: Phil Sutter <phil@nwl.cc>
I've updated Jose's patch to make it slightly simpler (eg: calloc instead
of malloc+memset), and ported it to 4.2.0 which requires it as well, and
attached it to this e-mail.
I can confirm that with this patch 4.1.1 doesn't segfault on me anymore.
The commit message should be reworked I guess though everything's in it
and I didn't want to modify his description.
Can it be merged as-is or should I reword the commit message and reference
Jose as the fix reporter ? We should not let this bug live forever.
From: "j.ps@openmailbox.org" <j.ps@openmailbox.org>
Essentially all that is needed to get rid of this issue is the
addition of:
memset(u, 0, sizeof(*u));
after:
if (!(u = malloc(sizeof(*u))))
break;
Also patched some other situations (strcpy and sprintf uses) that
potentially produce the same results.
Signed-off-by: Jose P Santos <j.ps@openmailbox.org>
[ wt: made Jose's patch slightly simpler, all credits to him for the diag ]
Signed-off-by: Willy Tarreau <w@1wt.eu>
Commit 1527a17 introduced a change where the second of two ssfilter_parse()
calls in ss.c was moved outside of a conditional block (ss.c: ~3575). This
commit enabled the parsing of services, such as 'sport = :ssh', but
inadvertently broke the '-F' file-based filtering:
Hi:
I found a formatting bug in the 4.1.1 ss command. The following line was
incorrectly output due to passing a negative length to printf() when
displaying the local address. In this instance hostapd does a "bind to
device" on cdreth0 and then does a udp "in address any" port 67 bind.
Please note the whitespace between the '*' and ' %cdreth0:67'
'udp UNCONN 0 0 ** %cdreth0:67* *:* users:(("hostapd",pid=19241,fd=5))'
Attached is my patch for the bug fix, it might be prudent to add more
guard code looking for negative length format codes.
Sincerely, Mike
This was working before, but only if realloc a) succeeded and b) did not
move the buffer to a different location. ''**buf = **new_buf' then
writes the value of *new_buf's first field into that of *buf.
Signed-off-by: Phil Sutter <phil@nwl.cc>
It really partially reverts:
ec4d0d8a9d (ss: Replace unixstat struct by new sockstat struct)
but adds few fields (name & peer_name) from removed unixstat to sockstat struct to easy
return original code.
Fixes: ec4d0d8a9d (ss: Replace unixstat struct by new sockstat struct)
Reported-by: Marc Dietrich <marvin24@gmx.de>
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
After commit 8250bc9ff4 ("ss: Unify inet sockets output") raw sockets
are displayed as udp because dgram_show_line() is used for both and
thus IPPROTO_UDP is used for both so proto_name() returns "udp".
Fix this by checking dg_proto which is set according to the caller of
dgram_show_line().
Reported-by: Miha Marolt <miham@beyondsemi.com>
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
If available and set, print 'v6only:1' for AF_INET6 sockets upon request
of extended information. For IPv6 sockets bound to in6addr_any, this is
the only way to determine if they will also accept IPv4 requests or not.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Use the IPv4/IPv6/TCP/UDP multicast groups of NETLINK_SOCK_DIAG
to filter and display socket statistics as they are destroyed.
Kernel support patch series: 24029a3603cfa633e8bc2b3fb3e48e76c497831d
Signed-off-by: Craig Gallek <kraig@google.com>
s->local.data is a pointer to a field of a non-NULL struct, and hence
cannot be NULL, thus comparing it to 0 is always false, and thus the
return is always false.
Presumably this was meant to be a check whether s->local.data[0] (which
I believe stores af_packet protocol) is 0, ie. ANY.
Change-Id: Ia232f5b06ce081e3b2fb6338f1a709cd94e03ae5
Fixes:
ss.c:1018:37: error: comparison of array 's->local.data' equal to a null pointer is always false [-Werror,-Wtautological-pointer-compare]
return s->lport == 0 && s->local.data == 0;
~~~~~~~~~^~~~ ~
1 error generated.
ss currently dumps IPv4 sockets, then IPv6 sockets from the kernel,
even if -4 or -6 option was given. Filtering in user space then has to
drop all sockets of wrong family. Such a waste of time...
Before :
$ time ss -tn -4 | wc -l
251659
real 0m1.241s
user 0m0.423s
sys 0m0.806s
After:
$ time ss -tn -4 | wc -l
251672
real 0m0.779s
user 0m0.412s
sys 0m0.386s
Signed-off-by: Eric Dumazet <edumazet@google.com>
Lets implement a full cache with proper hash table, memory got cheaper
these days.
Before :
$ time ss -t | wc -l
529678
real 0m22.708s
user 0m19.591s
sys 0m2.969s
After :
$ time ss -t | wc -l
528291
real 0m5.078s
user 0m4.099s
sys 0m0.985s
Signed-off-by: Eric Dumazet <edumazet@google.com>
On Fri, 2015-05-29 at 13:30 +0300, Vadim Kochan wrote:
> From: Vadim Kochan <vadim4j@gmail.com>
>
> Use strdup instead of malloc, and get rid of bad strcpy.
>
> Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
> ---
> misc/ss.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/misc/ss.c b/misc/ss.c
> index 347e3a1..a719466 100644
> --- a/misc/ss.c
> +++ b/misc/ss.c
> @@ -1908,8 +1908,7 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
>
> if (tb[INET_DIAG_CONG]) {
> const char *cong_attr = rta_getattr_str(tb[INET_DIAG_CONG]);
> - s.cong_alg = malloc(strlen(cong_attr + 1));
> - strcpy(s.cong_alg, cong_attr);
> + s.cong_alg = strdup(cong_attr);
> }
>
> if (TCPI_HAS_OPT(info, TCPI_OPT_WSCALE)) {
I doubt TCP_CA_NAME_MAX will ever change in the kernel : 16 bytes.
Its typically "cubic" and less than 8 bytes.
Using 8 bytes to point to a malloc(8) is a waste.
Please remove the memory allocation, or store the pointer, since
tcp_show_info() does the malloc()/free() before return.
Missing space before dctcp: markers.
With dctcp, cwnd=2 is pretty common, just display cwnd value even
if cwnd has this value, it makes parsing easier.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Kernel can give us smaller tcp_info than our.
We copy the kernel provided structure and fill with 0
the remaining part.
Lets clear only the missing part to save some cycles, as we intend to
slightly increase tcp_info size in the future.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Fixed applying family & socket type filters.
It was not possible to select UDP & UNIX sockets together.
Now selected families are ORed.
The problem was that filters were combined by AND.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Reported-By: Mihai Moldovan <ionic@ionic.de>
Seems expression parser did not work correctly some
long time and such simple things did not work too:
# ss -a '( sport = :ssh )'
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>