]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - misc/ss.c
ss: add fastopen support
[mirror_iproute2.git] / misc / ss.c
index ff7c194d58151350bdd5d707e89c9bb9dc54fd36..54936308484fe430315b69284322f6e1716a064f 100644 (file)
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -32,7 +32,7 @@
 #include "libnetlink.h"
 #include "SNAPSHOT.h"
 
-#include <netinet/tcp.h>
+#include <linux/tcp.h>
 #include <linux/sock_diag.h>
 #include <linux/inet_diag.h>
 #include <linux/unix_diag.h>
@@ -399,32 +399,32 @@ static int get_slabstat(struct slabstat *s)
 
 static const char *sstate_name[] = {
        "UNKNOWN",
-       [TCP_ESTABLISHED] = "ESTAB",
-       [TCP_SYN_SENT] = "SYN-SENT",
-       [TCP_SYN_RECV] = "SYN-RECV",
-       [TCP_FIN_WAIT1] = "FIN-WAIT-1",
-       [TCP_FIN_WAIT2] = "FIN-WAIT-2",
-       [TCP_TIME_WAIT] = "TIME-WAIT",
-       [TCP_CLOSE] = "UNCONN",
-       [TCP_CLOSE_WAIT] = "CLOSE-WAIT",
-       [TCP_LAST_ACK] = "LAST-ACK",
-       [TCP_LISTEN] =  "LISTEN",
-       [TCP_CLOSING] = "CLOSING",
+       [SS_ESTABLISHED] = "ESTAB",
+       [SS_SYN_SENT] = "SYN-SENT",
+       [SS_SYN_RECV] = "SYN-RECV",
+       [SS_FIN_WAIT1] = "FIN-WAIT-1",
+       [SS_FIN_WAIT2] = "FIN-WAIT-2",
+       [SS_TIME_WAIT] = "TIME-WAIT",
+       [SS_CLOSE] = "UNCONN",
+       [SS_CLOSE_WAIT] = "CLOSE-WAIT",
+       [SS_LAST_ACK] = "LAST-ACK",
+       [SS_LISTEN] =   "LISTEN",
+       [SS_CLOSING] = "CLOSING",
 };
 
 static const char *sstate_namel[] = {
        "UNKNOWN",
-       [TCP_ESTABLISHED] = "established",
-       [TCP_SYN_SENT] = "syn-sent",
-       [TCP_SYN_RECV] = "syn-recv",
-       [TCP_FIN_WAIT1] = "fin-wait-1",
-       [TCP_FIN_WAIT2] = "fin-wait-2",
-       [TCP_TIME_WAIT] = "time-wait",
-       [TCP_CLOSE] = "unconnected",
-       [TCP_CLOSE_WAIT] = "close-wait",
-       [TCP_LAST_ACK] = "last-ack",
-       [TCP_LISTEN] =  "listening",
-       [TCP_CLOSING] = "closing",
+       [SS_ESTABLISHED] = "established",
+       [SS_SYN_SENT] = "syn-sent",
+       [SS_SYN_RECV] = "syn-recv",
+       [SS_FIN_WAIT1] = "fin-wait-1",
+       [SS_FIN_WAIT2] = "fin-wait-2",
+       [SS_TIME_WAIT] = "time-wait",
+       [SS_CLOSE] = "unconnected",
+       [SS_CLOSE_WAIT] = "close-wait",
+       [SS_LAST_ACK] = "last-ack",
+       [SS_LISTEN] =   "listening",
+       [SS_CLOSING] = "closing",
 };
 
 struct tcpstat
@@ -1327,6 +1327,29 @@ static char *sprint_bw(char *buf, double bw)
        return buf;
 }
 
+static void print_skmeminfo(struct rtattr *tb[], int attrtype)
+{
+       const __u32 *skmeminfo;
+       if (!tb[attrtype])
+               return;
+       skmeminfo = RTA_DATA(tb[attrtype]);
+
+       printf(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
+              skmeminfo[SK_MEMINFO_RMEM_ALLOC],
+              skmeminfo[SK_MEMINFO_RCVBUF],
+              skmeminfo[SK_MEMINFO_WMEM_ALLOC],
+              skmeminfo[SK_MEMINFO_SNDBUF],
+              skmeminfo[SK_MEMINFO_FWD_ALLOC],
+              skmeminfo[SK_MEMINFO_WMEM_QUEUED],
+              skmeminfo[SK_MEMINFO_OPTMEM]);
+
+       if (RTA_PAYLOAD(tb[attrtype]) >=
+               (SK_MEMINFO_BACKLOG + 1) * sizeof(__u32))
+               printf(",bl%u", skmeminfo[SK_MEMINFO_BACKLOG]);
+
+       printf(")");
+}
+
 static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r)
 {
        struct rtattr * tb[INET_DIAG_MAX+1];
@@ -1337,22 +1360,7 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r)
                     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
        if (tb[INET_DIAG_SKMEMINFO]) {
-               const __u32 *skmeminfo = RTA_DATA(tb[INET_DIAG_SKMEMINFO]);
-
-               printf(" skmem:(r%u,rb%u,t%u,tb%u,f%u,w%u,o%u",
-                       skmeminfo[SK_MEMINFO_RMEM_ALLOC],
-                       skmeminfo[SK_MEMINFO_RCVBUF],
-                       skmeminfo[SK_MEMINFO_WMEM_ALLOC],
-                       skmeminfo[SK_MEMINFO_SNDBUF],
-                       skmeminfo[SK_MEMINFO_FWD_ALLOC],
-                       skmeminfo[SK_MEMINFO_WMEM_QUEUED],
-                       skmeminfo[SK_MEMINFO_OPTMEM]);
-
-               if (RTA_PAYLOAD(tb[INET_DIAG_SKMEMINFO]) >=
-                       (SK_MEMINFO_BACKLOG + 1) * sizeof(__u32))
-                       printf(",bl%u", skmeminfo[SK_MEMINFO_BACKLOG]);
-
-               printf(")");
+               print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
        } else if (tb[INET_DIAG_MEMINFO]) {
                const struct inet_diag_meminfo *minfo
                        = RTA_DATA(tb[INET_DIAG_MEMINFO]);
@@ -1384,6 +1392,8 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r)
                                printf(" ecn");
                        if (info->tcpi_options & TCPI_OPT_ECN_SEEN)
                                printf(" ecnseen");
+                       if (info->tcpi_options & TCPI_OPT_SYN_DATA)
+                               printf(" fastopen");
                }
 
                if (tb[INET_DIAG_CONG])
@@ -2139,7 +2149,7 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
        struct rtattr *tb[UNIX_DIAG_MAX+1];
        char name[128];
        int peer_ino;
-       int rqlen;
+       __u32 rqlen, wqlen;
 
        parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
                     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
@@ -2150,12 +2160,16 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
        if (state_width)
                printf("%-*s ", state_width, sstate_name[r->udiag_state]);
 
-       if (tb[UNIX_DIAG_RQLEN])
-               rqlen = *(int *)RTA_DATA(tb[UNIX_DIAG_RQLEN]);
-       else
+       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;
+       }
 
-       printf("%-6d %-6d ", rqlen, 0);
+       printf("%-6u %-6u ", rqlen, wqlen);
 
        if (tb[UNIX_DIAG_NAME]) {
                int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
@@ -2168,7 +2182,7 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
                sprintf(name, "*");
 
        if (tb[UNIX_DIAG_PEER])
-               peer_ino = *(int *)RTA_DATA(tb[UNIX_DIAG_PEER]);
+               peer_ino = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
        else
                peer_ino = 0;
 
@@ -2184,6 +2198,11 @@ static int unix_show_sock(struct nlmsghdr *nlh, struct filter *f)
                        printf(" users:(%s)", ubuf);
        }
 
+       if (show_mem) {
+               printf("\n\t");
+               print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
+       }
+
        printf("\n");
 
        return 0;
@@ -2210,6 +2229,8 @@ static int unix_show_netlink(struct filter *f, FILE *dump_fp)
        req.r.sdiag_family = AF_UNIX;
        req.r.udiag_states = f->states;
        req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN;
+       if (show_mem)
+               req.r.udiag_show |= UDIAG_SHOW_MEMINFO;
 
        if (send(fd, &req, sizeof(req), 0) < 0) {
                close(fd);