From patchwork Mon Aug 10 18:52:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Tafelmeier X-Patchwork-Id: 505768 X-Patchwork-Delegate: shemminger@vyatta.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id DD2F1140326 for ; Tue, 11 Aug 2015 04:53:11 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932677AbbHJSxJ (ORCPT ); Mon, 10 Aug 2015 14:53:09 -0400 Received: from mout.gmx.net ([212.227.17.20]:54432 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932453AbbHJSw7 (ORCPT ); Mon, 10 Aug 2015 14:52:59 -0400 Received: from punraz.Speedport_W_921V_1_37_000 ([79.203.93.221]) by mail.gmx.com (mrgmx101) with ESMTPSA (Nemesis) id 0MTO3f-1ZHtkN3lW3-00SSLD; Mon, 10 Aug 2015 20:52:41 +0200 From: Matthias Tafelmeier To: netdev@vger.kernel.org Cc: hagen@jauu.net, shemminger@osdl.org, fw@strlen.de, edumazet@google.com, daniel@iogearbox.net Subject: [PATCH 06/10] ss: replaced old output mechanisms with fmt handlers interfaces Date: Mon, 10 Aug 2015 20:52:20 +0200 Message-Id: <1439232744-19505-7-git-send-email-matthias.tafelmeier@gmx.net> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1439232744-19505-1-git-send-email-matthias.tafelmeier@gmx.net> References: <1439232744-19505-1-git-send-email-matthias.tafelmeier@gmx.net> X-Provags-ID: V03:K0:8ejcLcu4nmWqzcYkTsbPTTCezjE5mnXDB34sGdqgKUiUUlB7cDL b5XLVk9maUav8LQykyRBh4uF2YAFv/m/O+shOa/Twk6MyoE0Bkx+veWxap5+ojkDktLv3S0 XSdOLJG/jOgpBU5y7czCEI4n7O63y9WgqHbQcxT5m6MSgjBf7u8ABYuGH/412SV3vXUUG9e L3Wos653Ib6IcYcXiKJkA== X-UI-Out-Filterresults: notjunk:1; V01:K0:/o37nMiNs0c=:1HFa9i3Xcv2CZcdEMu2fxE 3PFPdS4Q9w9MjJ+xxByCy0SA/LAf1q8Vwr+Hhyb2OyPwsL56vmCZcIi30cmfnRVlafMoT12fK ksRrQmmry9qGfxcE2kWqM2r6vl3+DW02HAAePph17HcX7ITIXQVNw1Yl1yw47GBQrFOPEfQDH 9bf147PAPWrBCBnsAPrPAjDJT7QYpRMeoHMUgZ8AJ5bujePQF1V2yff9IYFFlAyj1CDEPtd5e uN5rxEi5lWn1cH/vkOfFDM0ofZehmztpNZfKiqie+ZthT2P2eUBBkHuVg1QdlcsjZv+w6RVEY 42+zk1zqgVsTcH7j2rBGC+jdc7ZVjbLtTLjjXJNiBbDJPD2tju0oItOHD2fYo1+x+SQ4qw85h PaFGiL91Sh9hvucq0Os/PfMFvTiR4nNIhOMj6HAYFqpnwNkKt10q5Uv0jPRpyMfKIkRIKvlRy lKX38yEZwVObAPTqNxAUrYXWY6vCbmOvUDyQ3QeLsUQFnp8ZiiIyGTnBZOrzhHyFdU99yjQZ4 3QK8vlXHawijf/HUtSDan720TE+U/P2o2rL/8PnMgBAB1p+em2BMpv6vIRhlKJBZsHUxRQCdY 5yxRY7lxH7TGMvQSuJ6nIfbCSDEPSzdR4ChivtPihlk46nbo0P7ipZRcO0rh/2lfbvmdhzRnh gBekHRnG7TmoTjymEfmAHMbKWjDIDxSDPmrkoEthNvfYyCsAEvxmIBwbgAkRV0xfEf3JZz+e2 yhs7fw8vwCcQ/djk Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Now, since the fmt (json, hr) handlers are in place, all can be output via these newly deviced code parts. Signed-off-by: Matthias Tafelmeier Suggested-by: Hagen Paul Pfeifer --- misc/ss.c | 330 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 152 insertions(+), 178 deletions(-) diff --git a/misc/ss.c b/misc/ss.c index 8fb6e7d..993a87b 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -105,6 +105,7 @@ int show_sock_ctx = 0; int user_ent_hash_build_init = 0; int follow_events = 0; int json_output = 0; +int json_first_elem = 1; int netid_width; int state_width; @@ -113,6 +114,8 @@ int addr_width; int serv_width; int screen_width; +enum out_fmt_type fmt_type = FMT_HR; + static const char *TCP_PROTO = "tcp"; static const char *UDP_PROTO = "udp"; static const char *RAW_PROTO = "raw"; @@ -346,6 +349,16 @@ static FILE *ephemeral_ports_open(void) #define USER_ENT_HASH_SIZE 256 struct user_ent *user_ent_hash[USER_ENT_HASH_SIZE]; +static void json_print_opening(void) +{ + if (json_output && json_first_elem) { + json_first_elem = 0; + printf("{\n"); + } else if (json_output) { + printf(",\n{\n"); + } +} + static int user_ent_hashfn(unsigned int ino) { int val = (ino >> 24) ^ (ino >> 16) ^ (ino >> 8) ^ ino; @@ -791,7 +804,8 @@ do_numeric: return buf; } -static void inet_addr_print(const inet_prefix *a, int port, unsigned int ifindex) +static void inet_addr_print(const inet_prefix *a, int port, + unsigned int ifindex, char *peer_kind) { char buf[1024]; const char *ap = buf; @@ -819,8 +833,8 @@ static void inet_addr_print(const inet_prefix *a, int port, unsigned int ifindex est_len -= strlen(ifname) + 1; /* +1 for percent char */ } - sock_addr_print_width(est_len, ap, ":", serv_width, resolve_service(port), - ifname); + sock_addr_fmt(ap, est_len, ":", serv_width, resolve_service(port), + ifname, peer_kind); } static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p, @@ -1352,21 +1366,27 @@ static void inet_stats_print(struct sockstat *s, int protocol) { char *buf = NULL; - sock_state_print(s, proto_name(protocol)); + sock_state_fmt(s, sstate_name, proto_name(protocol), + netid_width, state_width); - inet_addr_print(&s->local, s->lport, s->iface); - inet_addr_print(&s->remote, s->rport, 0); + if (json_output) + printf("\t,\"peers\": {\n"); + + inet_addr_print(&s->local, s->lport, s->iface, "local"); + inet_addr_print(&s->remote, s->rport, 0, "remote"); + if (json_output) + printf("}"); if (show_proc_ctx || show_sock_ctx) { if (find_entry(s->ino, &buf, - (show_proc_ctx & show_sock_ctx) ? - PROC_SOCK_CTX : PROC_CTX) > 0) { - printf(" users:(%s)", buf); + (show_proc_ctx & show_sock_ctx) ? + PROC_SOCK_CTX : PROC_CTX) > 0) { + sock_users_fmt(buf); free(buf); } } else if (show_users) { if (find_entry(s->ino, &buf, USERS) > 0) { - printf(" users:(%s)", buf); + sock_users_fmt(buf); free(buf); } } @@ -1470,16 +1490,16 @@ static int tcp_show_line(char *line, const struct filter *f, int family) inet_stats_print(&s.ss, IPPROTO_TCP); if (show_options) - tcp_timer_print(&s); + tcp_timer_fmt(&s); if (show_details) { - sock_details_print(&s.ss); + sock_details_fmt(&s.ss, GENERIC_DETAIL, 0, 0); if (opt[0]) - printf(" opt:\"%s\"", opt); + opt_fmt(opt); } if (show_tcpinfo) - tcp_stats_print(&s); + tcp_stats_fmt(&s); printf("\n"); return 0; @@ -1523,31 +1543,14 @@ static void print_skmeminfo(struct rtattr *tb[], int attrtype) const struct inet_diag_meminfo *minfo = RTA_DATA(tb[INET_DIAG_MEMINFO]); - printf(" mem:(r%u,w%u,f%u,t%u)", - minfo->idiag_rmem, - minfo->idiag_wmem, - minfo->idiag_fmem, - minfo->idiag_tmem); + mem_fmt(minfo); } 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(")"); + skmem_fmt(skmeminfo, tb, attrtype); } #define TCPI_HAS_OPT(info, opt) !!(info->tcpi_options & (opt)) @@ -1660,8 +1663,11 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r, s.bytes_received = info->tcpi_bytes_received; s.segs_out = info->tcpi_segs_out; s.segs_in = info->tcpi_segs_in; - tcp_stats_print(&s); - free(s.dctcp); + tcp_stats_fmt(&s); + if (s.dctcp) + free(s.dctcp); + if (s.cong_alg) + free(s.cong_alg); } } @@ -1685,6 +1691,8 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol) s.iface = r->id.idiag_if; s.sk = cookie_sk_get(&r->id.idiag_cookie[0]); + json_print_opening(); + if (s.local.family == AF_INET) { s.local.bytelen = s.remote.bytelen = 4; } else { @@ -1708,29 +1716,29 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol) t.timer = r->idiag_timer; t.timeout = r->idiag_expires; t.retrans = r->idiag_retrans; - tcp_timer_print(&t); + tcp_timer_fmt(&t); } if (show_details) { - sock_details_print(&s); - if (s.local.family == AF_INET6 && tb[INET_DIAG_SKV6ONLY]) { - unsigned char v6only; - v6only = *(__u8 *)RTA_DATA(tb[INET_DIAG_SKV6ONLY]); - printf(" v6only:%u", v6only); - } + sock_details_fmt(&s, GENERIC_DETAIL, 0, 0); if (tb[INET_DIAG_SHUTDOWN]) { unsigned char mask; mask = *(__u8 *)RTA_DATA(tb[INET_DIAG_SHUTDOWN]); - printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>'); + sock_conn_fmt(mask); } } if (show_mem || show_tcpinfo) { - printf("\n\t"); + if (!json_output) + printf("\n\t"); tcp_show_info(nlh, r, tb); } - printf("\n"); + if (json_output) + printf("}\n"); + else + printf("\n"); + return 0; } @@ -2081,7 +2089,10 @@ static int dgram_show_line(char *line, const struct filter *f, int family) inet_stats_print(&s, dg_proto == UDP_PROTO ? IPPROTO_UDP : 0); if (show_details && opt[0]) - printf(" opt:\"%s\"", opt); + opt_fmt(opt); + + if (json_output) + printf("}"); printf("\n"); return 0; @@ -2258,27 +2269,37 @@ static void unix_stats_print(struct sockstat *list, struct filter *f) continue; } - sock_state_print(s, unix_netid_name(s->type)); + sock_state_fmt(s, sstate_name, + unix_netid_name(s->type), netid_width, state_width); + + if (json_output) + printf("\t,\"peers\": {\n"); - sock_addr_print(s->name ?: "*", " ", - int_to_str(s->lport, port_name), NULL); - sock_addr_print(peer, " ", int_to_str(s->rport, port_name), - NULL); + sock_addr_fmt(s->name ?: "*", addr_width, + " ", serv_width, + int_to_str(s->lport, port_name), + NULL, "local"); + sock_addr_fmt(peer, addr_width, " ", serv_width, + int_to_str(s->rport, port_name), + NULL, "remote"); + if (json_output) + printf("}\n"); if (show_proc_ctx || show_sock_ctx) { if (find_entry(s->ino, &ctx_buf, - (show_proc_ctx & show_sock_ctx) ? - PROC_SOCK_CTX : PROC_CTX) > 0) { - printf(" users:(%s)", ctx_buf); + (show_proc_ctx & show_sock_ctx) ? + PROC_SOCK_CTX : PROC_CTX) > 0) { + sock_users_fmt(ctx_buf); free(ctx_buf); } } else if (show_users) { if (find_entry(s->ino, &ctx_buf, USERS) > 0) { - printf(" users:(%s)", ctx_buf); + sock_users_fmt(ctx_buf); free(ctx_buf); } } - printf("\n"); + if (!json_output) + printf("\n"); } } @@ -2291,7 +2312,9 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh, char name[128]; struct sockstat stat = { .name = "*", .peer_name = "*" }; - parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1), + json_print_opening(); + + parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr *)(r + 1), nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); stat.type = r->udiag_type; @@ -2324,21 +2347,27 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh, return 0; unix_stats_print(&stat, f); - - if (show_mem) { - printf("\t"); +if (show_mem) { + if (!json_output) + printf("\t"); print_skmeminfo(tb, UNIX_DIAG_MEMINFO); } if (show_details) { if (tb[UNIX_DIAG_SHUTDOWN]) { unsigned char mask; mask = *(__u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]); - printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>'); + sock_conn_fmt(mask); } } if (show_mem || show_details) - printf("\n"); + if (!json_output) + printf("\n"); + if (json_output) + printf("}\n"); + + if (name) + free(name); return 0; } @@ -2480,7 +2509,8 @@ static int packet_stats_print(struct sockstat *s, const struct filter *f) return 1; } - sock_state_print(s, s->type == SOCK_RAW ? "p_raw" : "p_dgr"); + sock_state_fmt(s, sstate_name, s->type == SOCK_RAW ? "p_raw" : "p_dgr", + netid_width, state_width); if (s->prot == 3) addr = "*"; @@ -2492,25 +2522,35 @@ static int packet_stats_print(struct sockstat *s, const struct filter *f) else port = xll_index_to_name(s->iface); - sock_addr_print(addr, ":", port, NULL); - sock_addr_print("", "*", "", NULL); + if (json_output) + printf("\t,\"peers\": {\n"); + + sock_addr_fmt(addr, addr_width, ":", + serv_width, port, + NULL, "local"); + sock_addr_fmt("", addr_width, "*", + serv_width, "", + NULL, "remote"); + + if (json_output) + printf("}\n"); if (show_proc_ctx || show_sock_ctx) { if (find_entry(s->ino, &buf, - (show_proc_ctx & show_sock_ctx) ? - PROC_SOCK_CTX : PROC_CTX) > 0) { - printf(" users:(%s)", buf); + (show_proc_ctx & show_sock_ctx) ? + PROC_SOCK_CTX : PROC_CTX) > 0) { + sock_users_fmt(buf); free(buf); } } else if (show_users) { if (find_entry(s->ino, &buf, USERS) > 0) { - printf(" users:(%s)", buf); + sock_users_fmt(buf); free(buf); } } if (show_details) - sock_details_print(s); + sock_details_fmt(s, GENERIC_DETAIL, 0, 0); return 0; } @@ -2527,7 +2567,9 @@ static int packet_show_sock(const struct sockaddr_nl *addr, uint32_t fanout = 0; bool has_fanout = false; - parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr*)(r+1), + json_print_opening(); + + 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 */ @@ -2567,60 +2609,9 @@ static int packet_show_sock(const struct sockaddr_nl *addr, if (packet_stats_print(&stat, f)) return 0; - if (show_details) { - if (pinfo) { - printf("\n\tver:%d", pinfo->pdi_version); - printf(" cpy_thresh:%d", pinfo->pdi_copy_thresh); - printf(" flags( "); - if (pinfo->pdi_flags & PDI_RUNNING) - printf("running"); - if (pinfo->pdi_flags & PDI_AUXDATA) - printf(" auxdata"); - if (pinfo->pdi_flags & PDI_ORIGDEV) - printf(" origdev"); - if (pinfo->pdi_flags & PDI_VNETHDR) - printf(" vnethdr"); - if (pinfo->pdi_flags & PDI_LOSS) - printf(" loss"); - if (!pinfo->pdi_flags) - printf("0"); - printf(" )"); - } - if (ring_rx) { - printf("\n\tring_rx("); - packet_show_ring(ring_rx); - printf(")"); - } - if (ring_tx) { - printf("\n\tring_tx("); - packet_show_ring(ring_tx); - printf(")"); - } - if (has_fanout) { - uint16_t type = (fanout >> 16) & 0xffff; - - printf("\n\tfanout("); - printf("id:%d,", fanout & 0xffff); - printf("type:"); - - if (type == 0) - printf("hash"); - else if (type == 1) - printf("lb"); - else if (type == 2) - printf("cpu"); - else if (type == 3) - printf("roll"); - else if (type == 4) - printf("random"); - else if (type == 5) - printf("qm"); - else - printf("0x%x", type); - - printf(")"); - } - } + if (show_details) + packet_details_fmt(pinfo, + ring_rx, ring_tx, fanout, has_fanout); if (show_bpf && tb[PACKET_DIAG_FILTER]) { struct sock_filter *fil = @@ -2628,15 +2619,15 @@ static int packet_show_sock(const struct sockaddr_nl *addr, int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) / sizeof(struct sock_filter); - printf("\n\tbpf filter (%d): ", num); - while (num) { - printf(" 0x%02x %u %u %u,", - fil->code, fil->jt, fil->jf, fil->k); - num--; - fil++; - } + bpf_filter_fmt(fil, num); } - printf("\n"); + + if (json_output) + printf("}\n"); + else + printf("\n"); + + return 0; } @@ -2712,6 +2703,7 @@ static int netlink_show_one(struct filter *f, SPRINT_BUF(prot_buf) = {}; const char *prot_name; char procname[64] = {}; + char *rem = "remote"; st.state = SS_CLOSE; st.rq = rq; @@ -2727,7 +2719,7 @@ static int netlink_show_one(struct filter *f, return 1; } - sock_state_print(&st, "nl"); + sock_state_fmt(&st, sstate_name, "nl", netid_width, state_width); if (resolve_services) prot_name = nl_proto_n2a(prot, prot_buf, sizeof(prot_buf)); @@ -2759,17 +2751,25 @@ static int netlink_show_one(struct filter *f, int_to_str(pid, procname); } - sock_addr_print(prot_name, ":", procname, NULL); + if (json_output) + printf("\t,\"peers\": {\n"); + + sock_addr_fmt(prot_name, addr_width, ":", serv_width, + procname, NULL, "local"); if (state == NETLINK_CONNECTED) { char dst_group_buf[30]; char dst_pid_buf[30]; - sock_addr_print(int_to_str(dst_group, dst_group_buf), ":", - int_to_str(dst_pid, dst_pid_buf), NULL); + sock_addr_fmt(int_to_str(dst_group, dst_group_buf), addr_width, + ":", serv_width, int_to_str(dst_pid, dst_pid_buf), + NULL, rem); } else { - sock_addr_print("", "*", "", NULL); + sock_addr_fmt("", addr_width, "*", serv_width, "", NULL, rem); } + if (json_output) + printf("}\n"); + char *pid_context = NULL; if (show_proc_ctx) { /* The pid value will either be: @@ -2783,16 +2783,11 @@ static int netlink_show_one(struct filter *f, else if (pid > 0) getpidcon(pid, &pid_context); - if (pid_context != NULL) { - printf("proc_ctx=%-*s ", serv_width, pid_context); - free(pid_context); - } else { - printf("proc_ctx=%-*s ", serv_width, "unavailable"); - } + proc_fmt(serv_width, pid_context); } if (show_details) { - printf(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups); + sock_details_fmt(&st, NETLINK_DETAIL, groups, cb); } printf("\n"); @@ -2808,7 +2803,9 @@ static int netlink_show_sock(const struct sockaddr_nl *addr, int rq = 0, wq = 0; unsigned long groups = 0; - parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr*)(r+1), + json_print_opening(); + + parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr *)(r + 1), nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); if (tb[NETLINK_DIAG_GROUPS] && RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS])) @@ -2834,6 +2831,9 @@ static int netlink_show_sock(const struct sockaddr_nl *addr, printf("\n"); } + if (json_output) + printf("}\n"); + return 0; } @@ -3028,7 +3028,7 @@ static int get_sockstat(struct ssummary *s) return 0; } -static int print_summary(void) +static int print_summary(bool has_successor) { struct ssummary s; struct snmpstat sn; @@ -3040,32 +3040,7 @@ static int print_summary(void) get_slabstat(&slabstat); - printf("Total: %d (kernel %d)\n", s.socks, slabstat.socks); - - printf("TCP: %d (estab %d, closed %d, orphaned %d, synrecv %d, timewait %d/%d), ports %d\n", - s.tcp_total + slabstat.tcp_syns + s.tcp_tws, - sn.tcp_estab, - s.tcp_total - (s.tcp4_hashed+s.tcp6_hashed-s.tcp_tws), - s.tcp_orphans, - slabstat.tcp_syns, - s.tcp_tws, slabstat.tcp_tws, - slabstat.tcp_ports - ); - - printf("\n"); - printf("Transport Total IP IPv6\n"); - printf("* %-9d %-9s %-9s\n", slabstat.socks, "-", "-"); - printf("RAW %-9d %-9d %-9d\n", s.raw4+s.raw6, s.raw4, s.raw6); - printf("UDP %-9d %-9d %-9d\n", s.udp4+s.udp6, s.udp4, s.udp6); - printf("TCP %-9d %-9d %-9d\n", s.tcp4_hashed+s.tcp6_hashed, s.tcp4_hashed, s.tcp6_hashed); - printf("INET %-9d %-9d %-9d\n", - s.raw4+s.udp4+s.tcp4_hashed+ - s.raw6+s.udp6+s.tcp6_hashed, - s.raw4+s.udp4+s.tcp4_hashed, - s.raw6+s.udp6+s.tcp6_hashed); - printf("FRAG %-9d %-9d %-9d\n", s.frag4+s.frag6, s.frag4, s.frag6); - - printf("\n"); + sock_summary_fmt(&s, &sn, &slabstat, has_successor); if (json_output && has_successor) printf(",\n"); @@ -3406,11 +3381,10 @@ int main(int argc, char *argv[]) argc -= optind; argv += optind; - if (do_summary) { - print_summary(); - if (do_default && argc == 0) - exit(0); - } + if (json_output) + printf("{\n"); + + /* Now parse filter... */ if (argc == 0 && filter_fp) {