From patchwork Thu Aug 17 17:36:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Julien Fortin X-Patchwork-Id: 802810 X-Patchwork-Delegate: shemminger@vyatta.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="TaZMC5Xx"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xYD7F2W6fz9t4X for ; Fri, 18 Aug 2017 03:42:17 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753685AbdHQRmO (ORCPT ); Thu, 17 Aug 2017 13:42:14 -0400 Received: from mail-wr0-f174.google.com ([209.85.128.174]:38271 "EHLO mail-wr0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753670AbdHQRmM (ORCPT ); Thu, 17 Aug 2017 13:42:12 -0400 Received: by mail-wr0-f174.google.com with SMTP id 5so25442568wrz.5 for ; Thu, 17 Aug 2017 10:42:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=seZT3GiKWDrMOYmYbX2Qg7ufF23HZWq48rOL8Epy+yA=; b=TaZMC5XxhXGsMo8DdX415q1S+eqw0e5Q5qddavlbg996/AAujGZQTKJ0UtE5AvYK/F Zv7cQ2zxbEdOjFpPTtiPIUUcb23WcQ0UBiTtXwudzpaS1L2RQqiWHV7AFGSNzWMcQoiT Dw8Z1nF0JiUbKmjl7uKLEEae5SB8s79dgeuqI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=seZT3GiKWDrMOYmYbX2Qg7ufF23HZWq48rOL8Epy+yA=; b=A7csbm7mA+JGAeqyJ+A6yRVJwO6DRwMSgjhY/WGrtGH//VERebrhTiTtk+boSpcrBo dhwyf5Php+7NFHA2kuocXCFyDWvYCAy7JjeBKlTrbpTZLXuQMw1j84VugujAqQWavhCm yOyHT/9WUzPUyV+3Oz/KzNDk+d7VNVMnO5PyaXIgPNwTVgm3NRHnxT7ogu0SudgsI1E6 Wb79PPcXNVZjzf/e3Yps5Dqun4WElXdNzuIuS26GlPKaLW0W01e1JriHzPke2LBwYqWb hGgEVpnDivdEEUR4L9ffIQ9wTSJJyyayjnNPiAt4ZYfgX0CMGZJsxAf9jLjecBLs04aE tUKA== X-Gm-Message-State: AHYfb5jLH3v29azez10QXolQ8SknfKLBV3IX3hh60u7OBXFEzDR9lPpE p8pNA00XurrwF+mb0SPhjNTi X-Received: by 10.223.162.217 with SMTP id t25mr4230451wra.68.1502991731225; Thu, 17 Aug 2017 10:42:11 -0700 (PDT) Received: from localhost.localdomain ([37.169.21.172]) by smtp.googlemail.com with ESMTPSA id k13sm3902040wrd.4.2017.08.17.10.41.59 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 17 Aug 2017 10:42:10 -0700 (PDT) From: Julien Fortin X-Google-Original-From: Julien Fortin To: netdev@vger.kernel.org Cc: roopa@cumulusnetworks.com, nikolay@cumulusnetworks.com, dsa@cumulusnetworks.com, Julien Fortin Subject: [PATCH iproute2 json v2 22/27] ip: link_ip6tnl.c: add json output support Date: Thu, 17 Aug 2017 10:36:09 -0700 Message-Id: <20170817173614.54987-23-julien@cumulusnetworks.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170817173614.54987-1-julien@cumulusnetworks.com> References: <20170817173614.54987-1-julien@cumulusnetworks.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Julien Fortin Schema { "proto": { "type": "string", "attr": "IFLA_IPTUN_PROTO" }, "remote": { "type": "string", "attr": "IFLA_IPTUN_REMOTE" }, "local": { "type": "string", "attr": "IFLA_IPTUN_LOCAL" }, "link": { "type": "string", "attr": "IFLA_IPTUN_LINK", "mutually_exclusive": { "link_index": { "type": "uint", } } }, "ip6_tnl_f_ign_encap_limit": { "type": "bool", "attr": "IP6_TNL_F_IGN_ENCAP_LIMIT" }, "encap_limit": { "type": "uint", "attr": "IFLA_IPTUN_ENCAP_LIMIT" }, "ttl": { "type": "uint", "attr": "IFLA_IPTUN_TTL" }, "ip6_tnl_f_use_orig_tclass": { "type": "", "attr": "IP6_TNL_F_USE_ORIG_TCLASS" }, "flowinfo_tclass": { "type": "string", "attr": "IP6_FLOWINFO_TCLASS" }, "ip6_tnl_f_use_orig_flowlabel": { "type": "bool", "attr": "IP6_TNL_F_USE_ORIG_FLOWLABEL" }, "flowlabel": { "type": "string", "attr": "IP6_FLOWINFO_FLOWLABEL" }, "flowinfo": { "type": "string" }, "ip6_tnl_f_rcv_dscp_copy": { "type": "bool", "attr": "IP6_TNL_F_RCV_DSCP_COPY" }, "ip6_tnl_f_mip6_dev": { "type": "bool", "attr": "IP6_TNL_F_MIP6_DEV" }, "ip6_tnl_f_use_orig_fwmark": { "type": "bool", "attr": "IP6_TNL_F_USE_ORIG_FWMARK" }, "encap": { "type": "dict", "attr": "IFLA_IPTUN_ENCAP_TYPE", "dict": { "type": { "type": "string", "attr": "IFLA_IPTUN_ENCAP_TYPE" }, "sport": { "type": "uint", "attr": "IFLA_IPTUN_ENCAP_SPORT" }, "dport": { "type": "uint", "attr": "IFLA_IPTUN_ENCAP_DPORT" }, "csum": { "type": "bool", "attr": "TUNNEL_ENCAP_FLAG_CSUM" }, "csum6": { "type": "bool", "attr": "TUNNEL_ENCAP_FLAG_CSUM6" }, "remcsum": { "type": "bool", "attr": "TUNNEL_ENCAP_FLAG_REMCSUM" } } } } $ ip link show $ ip -6 tunnel add name tun6 mode ip6gre local 2001:db8:1::1/64 remote 2001:0db8:85a3:0000:0000:8a2e:0370:7334 $ ip link show 10: ip6tnl0@NONE: mtu 1452 qdisc noop state DOWN mode DEFAULT group default link/tunnel6 :: brd :: 11: ip6gre0@NONE: mtu 1448 qdisc noop state DOWN mode DEFAULT group default link/gre6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 12: tun6@NONE: mtu 1448 qdisc noop state DOWN mode DEFAULT group default link/gre6 20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01 peer 20:01:0d:b8:85:a3:00:00:00:00:8a:2e:03:70:73:34 ➜ ~ ./ip -details -json link show [{ "ifindex": 10, "ifname": "ip6tnl0", "link": null, "flags": ["NOARP"], "mtu": 1452, "qdisc": "noop", "operstate": "DOWN", "linkmode": "DEFAULT", "group": "default", "link_type": "tunnel6", "address": "::", "broadcast": "::", "promiscuity": 0, "linkinfo": { "info_kind": "ip6tnl", "info_data": { "proto": "ip6ip6", "remote": "::", "local": "::", "encap_limit": 0, "ttl": 0, "flowinfo_tclass": "0x00", "flowlabel": "0x00000", "flowinfo": "0x00000000" } }, "inet6_addr_gen_mode": "eui64", "num_tx_queues": 1, "num_rx_queues": 1, "gso_max_size": 65536, "gso_max_segs": 65535 },{ "ifindex": 11, "ifname": "ip6gre0", "link": null, "flags": ["NOARP"], "mtu": 1448, "qdisc": "noop", "operstate": "DOWN", "linkmode": "DEFAULT", "group": "default", "link_type": "gre6", "address": "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", "broadcast": "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", "promiscuity": 0, "linkinfo": { "info_kind": "ip6gre", "info_data": { "remote": "any", "local": "any", "ttl": 0, "encap_limit": 0, "flowlabel": "0x00000" } }, "inet6_addr_gen_mode": "eui64", "num_tx_queues": 1, "num_rx_queues": 1, "gso_max_size": 65536, "gso_max_segs": 65535 },{ "ifindex": 12, "ifname": "tun6", "link": null, "flags": ["POINTOPOINT","NOARP"], "mtu": 1448, "qdisc": "noop", "operstate": "DOWN", "linkmode": "DEFAULT", "group": "default", "link_type": "gre6", "address": "20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01", "link_pointtopoint": true, "broadcast": "20:01:0d:b8:85:a3:00:00:00:00:8a:2e:03:70:73:34", "promiscuity": 0, "linkinfo": { "info_kind": "ip6gre", "info_data": { "remote": "2001:db8:85a3::8a2e:370:7334", "local": "2001:db8:1::1", "ttl": 64, "encap_limit": 4, "flowlabel": "0x00000" } }, "inet6_addr_gen_mode": "eui64", "num_tx_queues": 1, "num_rx_queues": 1, "gso_max_size": 65536, "gso_max_segs": 65535 } ] Signed-off-by: Julien Fortin --- ip/link_ip6tnl.c | 172 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 122 insertions(+), 50 deletions(-) diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c index 505fb476..a4199006 100644 --- a/ip/link_ip6tnl.c +++ b/ip/link_ip6tnl.c @@ -346,25 +346,29 @@ static void ip6tunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb if (tb[IFLA_IPTUN_PROTO]) { switch (rta_getattr_u8(tb[IFLA_IPTUN_PROTO])) { case IPPROTO_IPIP: - fprintf(f, "ipip6 "); + print_string(PRINT_ANY, "proto", "%s ", "ipip6"); break; case IPPROTO_IPV6: - fprintf(f, "ip6ip6 "); + print_string(PRINT_ANY, "proto", "%s ", "ip6ip6"); break; case 0: - fprintf(f, "any "); + print_string(PRINT_ANY, "proto", "%s ", "any"); break; } } if (tb[IFLA_IPTUN_REMOTE]) { - fprintf(f, "remote %s ", - rt_addr_n2a_rta(AF_INET6, tb[IFLA_IPTUN_REMOTE])); + print_string(PRINT_ANY, + "remote", + "remote %s ", + rt_addr_n2a_rta(AF_INET6, tb[IFLA_IPTUN_REMOTE])); } if (tb[IFLA_IPTUN_LOCAL]) { - fprintf(f, "local %s ", - rt_addr_n2a_rta(AF_INET6, tb[IFLA_IPTUN_LOCAL])); + print_string(PRINT_ANY, + "local", + "local %s ", + rt_addr_n2a_rta(AF_INET6, tb[IFLA_IPTUN_LOCAL])); } if (tb[IFLA_IPTUN_LINK] && rta_getattr_u32(tb[IFLA_IPTUN_LINK])) { @@ -372,93 +376,161 @@ static void ip6tunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb const char *n = if_indextoname(link, s2); if (n) - fprintf(f, "dev %s ", n); + print_string(PRINT_ANY, "link", "dev %s ", n); else - fprintf(f, "dev %u ", link); + print_uint(PRINT_ANY, "link_index", "dev %u ", link); } if (flags & IP6_TNL_F_IGN_ENCAP_LIMIT) - printf("encaplimit none "); + print_bool(PRINT_ANY, + "ip6_tnl_f_ign_encap_limit", + "encaplimit none ", + true); else if (tb[IFLA_IPTUN_ENCAP_LIMIT]) - fprintf(f, "encaplimit %u ", - rta_getattr_u8(tb[IFLA_IPTUN_ENCAP_LIMIT])); + print_uint(PRINT_ANY, + "encap_limit", + "encaplimit %u ", + rta_getattr_u8(tb[IFLA_IPTUN_ENCAP_LIMIT])); if (tb[IFLA_IPTUN_TTL]) - fprintf(f, "hoplimit %u ", rta_getattr_u8(tb[IFLA_IPTUN_TTL])); + print_uint(PRINT_ANY, + "ttl", + "hoplimit %u ", + rta_getattr_u8(tb[IFLA_IPTUN_TTL])); if (flags & IP6_TNL_F_USE_ORIG_TCLASS) - printf("tclass inherit "); + print_bool(PRINT_ANY, + "ip6_tnl_f_use_orig_tclass", + "tclass inherit ", + true); else if (tb[IFLA_IPTUN_FLOWINFO]) { __u32 val = ntohl(flowinfo & IP6_FLOWINFO_TCLASS); - printf("tclass 0x%02x ", (__u8)(val >> 20)); + if (is_json_context()) { + SPRINT_BUF(b1); + + snprintf(b1, sizeof(b1), "0x%02x", (__u8)(val >> 20)); + print_string(PRINT_JSON, "flowinfo_tclass", NULL, b1); + } else { + printf("tclass 0x%02x ", (__u8)(val >> 20)); + } + } + + if (flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) { + print_bool(PRINT_ANY, + "ip6_tnl_f_use_orig_flowlabel", + "flowlabel inherit ", + true); + } else { + if (is_json_context()) { + SPRINT_BUF(b1); + + snprintf(b1, sizeof(b1), "0x%05x", + ntohl(flowinfo & IP6_FLOWINFO_FLOWLABEL)); + print_string(PRINT_JSON, "flowlabel", NULL, b1); + } else { + printf("flowlabel 0x%05x ", + ntohl(flowinfo & IP6_FLOWINFO_FLOWLABEL)); + } } - if (flags & IP6_TNL_F_USE_ORIG_FLOWLABEL) - printf("flowlabel inherit "); - else - printf("flowlabel 0x%05x ", ntohl(flowinfo & IP6_FLOWINFO_FLOWLABEL)); + if (is_json_context()) { + SPRINT_BUF(flwinfo); - printf("(flowinfo 0x%08x) ", ntohl(flowinfo)); + snprintf(flwinfo, sizeof(flwinfo), "0x%08x", ntohl(flowinfo)); + print_string(PRINT_JSON, "flowinfo", NULL, flwinfo); + } else { + printf("(flowinfo 0x%08x) ", ntohl(flowinfo)); + + } if (flags & IP6_TNL_F_RCV_DSCP_COPY) - printf("dscp inherit "); + print_bool(PRINT_ANY, + "ip6_tnl_f_rcv_dscp_copy", + "dscp inherit ", + true); if (flags & IP6_TNL_F_MIP6_DEV) - fprintf(f, "mip6 "); + print_bool(PRINT_ANY, "ip6_tnl_f_mip6_dev", "mip6 ", true); + + if (flags & IP6_TNL_F_USE_ORIG_FWMARK) { + print_bool(PRINT_ANY, + "ip6_tnl_f_use_orig_fwmark", + "fwmark inherit ", + true); + } else if (tb[IFLA_IPTUN_FWMARK]) { + __u32 fwmark = rta_getattr_u32(tb[IFLA_IPTUN_FWMARK]); - if (flags & IP6_TNL_F_USE_ORIG_FWMARK) - fprintf(f, "fwmark inherit "); - else if (tb[IFLA_IPTUN_FWMARK] && rta_getattr_u32(tb[IFLA_IPTUN_FWMARK])) - fprintf(f, "fwmark 0x%x ", rta_getattr_u32(tb[IFLA_IPTUN_FWMARK])); + if (fwmark) { + SPRINT_BUF(b1); + + snprintf(b1, sizeof(b1), "0x%x", fwmark); + print_string(PRINT_ANY, "fwmark", "fwmark %s ", b1); + } + } if (tb[IFLA_IPTUN_ENCAP_TYPE] && - rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_TYPE]) != - TUNNEL_ENCAP_NONE) { + rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) { __u16 type = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_TYPE]); __u16 flags = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_FLAGS]); __u16 sport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_SPORT]); __u16 dport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_DPORT]); - fputs("encap ", f); + open_json_object("encap"); + print_string(PRINT_FP, NULL, "encap ", NULL); switch (type) { case TUNNEL_ENCAP_FOU: - fputs("fou ", f); + print_string(PRINT_ANY, "type", "%s ", "fou"); break; case TUNNEL_ENCAP_GUE: - fputs("gue ", f); + print_string(PRINT_ANY, "type", "%s ", "gue"); break; default: - fputs("unknown ", f); + print_null(PRINT_ANY, "type", "unknown ", NULL); break; } - if (sport == 0) - fputs("encap-sport auto ", f); - else - fprintf(f, "encap-sport %u", ntohs(sport)); + if (is_json_context()) { + print_uint(PRINT_JSON, + "sport", + NULL, + sport ? ntohs(sport) : 0); + print_uint(PRINT_JSON, "dport", NULL, ntohs(dport)); + print_bool(PRINT_JSON, "csum", NULL, + flags & TUNNEL_ENCAP_FLAG_CSUM); + print_bool(PRINT_JSON, "csum6", NULL, + flags & TUNNEL_ENCAP_FLAG_CSUM6); + print_bool(PRINT_JSON, "remcsum", NULL, + flags & TUNNEL_ENCAP_FLAG_REMCSUM); + close_json_object(); + } else { + if (sport == 0) + fputs("encap-sport auto ", f); + else + fprintf(f, "encap-sport %u", ntohs(sport)); - fprintf(f, "encap-dport %u ", ntohs(dport)); + fprintf(f, "encap-dport %u ", ntohs(dport)); - if (flags & TUNNEL_ENCAP_FLAG_CSUM) - fputs("encap-csum ", f); - else - fputs("noencap-csum ", f); + if (flags & TUNNEL_ENCAP_FLAG_CSUM) + fputs("encap-csum ", f); + else + fputs("noencap-csum ", f); - if (flags & TUNNEL_ENCAP_FLAG_CSUM6) - fputs("encap-csum6 ", f); - else - fputs("noencap-csum6 ", f); + if (flags & TUNNEL_ENCAP_FLAG_CSUM6) + fputs("encap-csum6 ", f); + else + fputs("noencap-csum6 ", f); - if (flags & TUNNEL_ENCAP_FLAG_REMCSUM) - fputs("encap-remcsum ", f); - else - fputs("noencap-remcsum ", f); + if (flags & TUNNEL_ENCAP_FLAG_REMCSUM) + fputs("encap-remcsum ", f); + else + fputs("noencap-remcsum ", f); + } } } static void ip6tunnel_print_help(struct link_util *lu, int argc, char **argv, - FILE *f) + FILE *f) { print_usage(f); }