What does the output of "ss -s" mean

The netstat utility has been replaced by the ss utility, and very often the output of aggregated (summary) information “ ss -s ” (or “ ss --summary ”) is used for monitoring needs. However, what does each of the displayed fields mean?

# ss -s
Total: 15046 (kernel 16739)
TCP:   39306 (estab 11458, closed 25092, orphaned 110, synrecv 0, timewait 24929/0), ports 0

Transport Total     IP        IPv6
*	  16739     -         -        
RAW	  0         0         0        
UDP	  15        5         10       
TCP	  14214     1214      13000    
INET	  14229     1219      13010    
FRAG	  0         0         0        

As it turned out, there are subtleties.

The source of truth is the source code. The source code of the utility «ss» found in iproute2 / the misc / ss.c . The output of "ss -s" is done in the print_summary function .

Prior to version 4.17.0, the output of “ss -s” is displayed above. After committing 90ee99d, it began to look like this:

# ss -s
Total: 15046
TCP:   39306 (estab 11458, closed 25092, orphaned 110, timewait 24929)

Transport Total     IP        IPv6
RAW	  0         0         0        
UDP	  15        5         10       
TCP	  14214     1214      13000    
INET	  14229     1219      13010    
FRAG	  0         0         0        

As you can see, the "kernel" field has been removed from the "Total" line. In the line “TCP”, the field “synrecv” was deleted, one (first) number “timewait” remained, the field “ports” was deleted. In the table "Transport" the row "*" was deleted. The general meaning of the commit can be translated as: " We have removed from the output what has long been broken ."

What was broken?


In print_summary version 4.16.0 is used structure slabstat , filled by calling get_slabstat . If we try to translate the get_slabstat call into shell commands, we get the following:

# egrep '^(sock|tcp_bind_bucket|tcp_tw_bucket|tcp_open_request|skbuff_head_cache)' /proc/slabinfo | awk '{ print $1, $2; }'

Where the keys from "/ proc / slabinfo" correspond to the fields of the "slabstat" structure:

struct slabstat {
	int socks;       // sock, net/core/sock.c:sk_init,   2.6.12
	int tcp_ports;   // tcp_bind_bucket, net/ipv4/tcp.c:tcp_init
	int tcp_tws;     // tcp_tw_bucket, net/ipv4/tcp.c:tcp_init,   2.6.14
	int tcp_syns;    // tcp_open_request, net/ipv4/tcp.c:tcp_init,   2.6.13
	int skbs;        // skbuff_head_cache, net/core/skbuff:skb_init,  
};

In other words, of all the values ​​obtained from "/ proc / slabinfo" today, only the value "tcp_bind_bucket" can be obtained, which is displayed in the "ports" field. I will give his description from the book “TCP / IP Architecture, Design, and Implementation in Linux. By S. Seth and MA Venkatesulu 2008 the IEEE Computer Society ":
This structure keeps information about the port number usage by sockets and the way the port number is being used. The information is useful enough to tell the new binding socket whether it can bind itself to a particular port number that is already in use. The data structure also keeps track of all the socket’s that are associated with this port number.
Now again the same thing, but in the form of a picture (the artist from me is so-so):



Do you notice anything strange? Slab “sock” (deleted in 2.6.12) has a nonzero value. The explanation is very simple - due to the peculiarities of string comparison, any number whose key begins with "sock" will get into the field value. In my case, this is “sock_inode_cache” from “net / socket.c: init_inodecache” related to “sockfs” - a list of “inodes” containing “socket struct” (maybe this is not quite what the author of the utility intended):

# egrep '^sock' /proc/slabinfo | awk '{ print $1, $2; }'
sock_inode_cache 16739

Well, “tcp_bind_bucket” is missing just because of the kernel build options (and, accordingly, the “ports” field always has the value “0”).

Output Description “ss -s”


Before diving into the intricacies of field calculations, it makes sense to refresh the state of sockets in memory (ESTABLISHED, CLOSE-WAIT, TIME-WAIT, etc.). For those who have forgotten, help wiki: RU , EN .

The output of the utility is based on the values ​​obtained from the files:

# cat /proc/net/sockstat
sockets: used 15046
TCP: inuse 1205 orphan 111 tw 24952 alloc 14368 mem 5890
UDP: inuse 5 mem 86
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

# cat /proc/net/sockstat6
TCP6: inuse 13000
UDP6: inuse 10
UDPLITE6: inuse 0
RAW6: inuse 0
FRAG6: inuse 0 memory 0

# egrep '^Tcp:' /proc/net/snmp
Tcp: RtoAlgorithm RtoMin RtoMax ... AttemptFails EstabResets CurrEstab ...
Tcp: 1 200 120000 ... 1348218 4095008 11458 ...

Values ​​calculated from the contents of "net / sockstat" (to simplify the perception in the pictures):



  • Total - the total number of sockets in the system (including unix sockets) in any state except TIME_WAIT;
  • TCP: - the total number of TCP sockets (including IPv6) in any state, tw sockets are separated from alloc sockets due to the so-called. " Death row " - they can not be used until the transition to the CLOSED state.
    • orphaned — «» TCP (, );
    • timewait — TCP TIME_WAIT;
    • inuse TCP, UDP, RAWv4 CLOSED TIME_WAIT;
    • inuse FRAG (bool) — , memory — ( mem, ).

Values ​​calculated by the contents of "net / sockstat6":



Everything seems to be simple here - " Transport / Total " is the sum-of-total sum of the " IP " and " IPv6 " values .

Values ​​calculated from the contents of "net / snmp". According to RFC-4022 , “ tcpCurrEstab ” is “The number of TCP connections for which the current state is either ESTABLISHED or CLOSE-WAIT”.



And the last “ closedfield is the sum of allocated sockets and sockets in TIME_WAIT state minus the sum of TCPv4 and TCPv6 sockets in any of the unclosed states:



PS And do not forget to sign the axes on the graphs.

All Articles