From patchwork Fri Aug 28 17:45:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andy Gospodarek X-Patchwork-Id: 511990 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 98BA71401CD for ; Sat, 29 Aug 2015 03:46:43 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b=TDXl2Z8s; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753138AbbH1Rql (ORCPT ); Fri, 28 Aug 2015 13:46:41 -0400 Received: from mail-pa0-f54.google.com ([209.85.220.54]:35586 "EHLO mail-pa0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753133AbbH1Rqj (ORCPT ); Fri, 28 Aug 2015 13:46:39 -0400 Received: by pacdd16 with SMTP id dd16so69329529pac.2 for ; Fri, 28 Aug 2015 10:46:39 -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:mime-version:content-type :content-transfer-encoding; bh=sFzIzk+88MtRu1+XdHX6hA47MdBs+eeUQ2FN1rP9RH4=; b=TDXl2Z8sXKrbnYen5y4H9sb5pkkXvJ5eJoLUF0XJaCTuO45/j1w6N7Ac0G1+TUmSgT lY2a2Tu0zkVddP5F706mJG4g++VGX85KVOZCu4mPuX3aDal+IqjAZbyzciHaHi63O43s PG+nXh3iov5/OUBKFus7RORPbfic6Xb5VrLaM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-type:content-transfer-encoding; bh=sFzIzk+88MtRu1+XdHX6hA47MdBs+eeUQ2FN1rP9RH4=; b=KDHga/3AUzkglq2OPbW0xrQubougv+3XymLtGbfvh2zdVcjv+tfMEBx0nfdfKFE30P ZzeT8WLCGaitbWLkNFBV997VaA33qqOZZ+XXBTNHhn64iQc4ZKVN03mmfB4P2js9v85X 5eXW8d6dcO0mGIyaqRMWEUh3tapIfPlge+jYgSJUlBcIPAi0tWLAj4ERA9i3nuMc19Yf 8uSNCQ4EFzE40zjrDpOTXLFSznf9cnOtj5b21oiCE6gutu1fqI+SBCCK909jwYYevaqA rXYWydEadv51lr961dNkGqjL/sFpa5ro5lLzDci4TCGtxBZ2lLd/PZ4WBObI3LEPPhke 7Idw== X-Gm-Message-State: ALoCoQlirkszsbbWzKkeva30Ua5dvda6g9QaMwfoH8EWroOZcooHFQKnI64umIHayPvLtjPBdEE+ X-Received: by 10.66.139.234 with SMTP id rb10mr17176907pab.118.1440783998964; Fri, 28 Aug 2015 10:46:38 -0700 (PDT) Received: from fedora-devel.cumulusnetworks.com (42-10-255-199.rev.celito.net. [199.255.10.42]) by smtp.googlemail.com with ESMTPSA id gu2sm6392377pbc.1.2015.08.28.10.46.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2015 10:46:38 -0700 (PDT) From: Andy Gospodarek To: netdev@vger.kernel.org Cc: Stephen Hemminger , Andy Gospodarek Subject: [PATCH iproute2 v3] add support for brief output for link and addresses Date: Fri, 28 Aug 2015 13:45:41 -0400 Message-Id: <1440783941-29597-1-git-send-email-gospo@cumulusnetworks.com> X-Mailer: git-send-email 1.9.3 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This adds support for slightly less output than is normally provided by 'ip link show' and 'ip addr show'. This is a bit better when you have a host with lots of interfaces. Sample output: $ ip -br link show lo UNKNOWN 00:00:00:00:00:00 p2p1 UP 08:00:27:ee:0b:3b p7p1 UP 08:00:27:9d:62:9f p8p1 DOWN 08:00:27:dc:d8:ca p9p1 UP 08:00:27:76:d9:75 p7p1.100@p7p1 UP 08:00:27:9d:62:9f $ ip -br -4 addr show lo UNKNOWN 127.0.0.1/8 p2p1 UP 192.168.56.2/24 p7p1 UP 70.0.0.1/24 p8p1 DOWN 80.0.0.1/24 p9p1 UP 10.0.5.15/24 p7p1.100@p7p1 UP 200.0.0.1/24 $ ip -br -6 addr show lo UNKNOWN ::1/128 p2p1 UP fe80::a00:27ff:feee:b3b/64 p7p1 UP 7000::1/8 fe80::a00:27ff:fe9d:629f/64 p8p1 DOWN 8000::1/8 p9p1 UP fe80::a00:27ff:fe76:d975/64 p7p1.100@p7p1 UP fe80::a00:27ff:fe9d:629f/64 $ ip -br addr show p7p1 p7p1 UP 70.0.0.1/24 7000::1/8 fe80::a00:27ff:fe9d:629f/64 v2: Now with color support! v3: Better field width estimation (except netdev names to keep output at a decent width) and whitespace fixup. Signed-off-by: Andy Gospodarek --- include/utils.h | 1 + ip/ip.c | 5 +- ip/ip_common.h | 3 + ip/ipaddress.c | 150 +++++++++++++++++++++++++++++++++++++++++++------- ip/iplink.c | 5 +- man/man8/ip-link.8.in | 3 +- 6 files changed, 143 insertions(+), 24 deletions(-) diff --git a/include/utils.h b/include/utils.h index 0c57ccd..f77edeb 100644 --- a/include/utils.h +++ b/include/utils.h @@ -19,6 +19,7 @@ extern int show_details; extern int show_raw; extern int resolve_hosts; extern int oneline; +extern int brief; extern int timestamp; extern int timestamp_short; extern const char * _SL_; diff --git a/ip/ip.c b/ip/ip.c index e75447e..eea00b8 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -32,6 +32,7 @@ int show_stats; int show_details; int resolve_hosts; int oneline; +int brief; int timestamp; const char *_SL_; int force; @@ -55,7 +56,7 @@ static void usage(void) " -h[uman-readable] | -iec |\n" " -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n" " -4 | -6 | -I | -D | -B | -0 |\n" -" -l[oops] { maximum-addr-flush-attempts } |\n" +" -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n" " -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n" " -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n"); exit(-1); @@ -250,6 +251,8 @@ int main(int argc, char **argv) if (argc <= 1) usage(); batch_file = argv[1]; + } else if (matches(opt, "-brief") == 0) { + ++brief; } else if (matches(opt, "-rcvbuf") == 0) { unsigned int size; diff --git a/ip/ip_common.h b/ip/ip_common.h index f120f5b..f74face 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -2,6 +2,9 @@ extern int get_operstate(const char *name); extern int print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); +extern int print_linkinfo_brief(const struct sockaddr_nl *who, + struct nlmsghdr *n, + void *arg); extern int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 13d9c46..2aa5fbf 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -138,13 +138,22 @@ static void print_operstate(FILE *f, __u8 state) if (state >= sizeof(oper_states)/sizeof(oper_states[0])) fprintf(f, "state %#x ", state); else { - fprintf(f, "state "); - if (strcmp(oper_states[state], "UP") == 0) - color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]); - else if (strcmp(oper_states[state], "DOWN") == 0) - color_fprintf(f, COLOR_OPERSTATE_DOWN, "%s ", oper_states[state]); - else - fprintf(f, "%s ", oper_states[state]); + if (brief) { + if (strcmp(oper_states[state], "UP") == 0) + color_fprintf(f, COLOR_OPERSTATE_UP, "%-14s ", oper_states[state]); + else if (strcmp(oper_states[state], "DOWN") == 0) + color_fprintf(f, COLOR_OPERSTATE_DOWN, "%-14s ", oper_states[state]); + else + fprintf(f, "%-14s ", oper_states[state]); + } else { + fprintf(f, "state "); + if (strcmp(oper_states[state], "UP") == 0) + color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]); + else if (strcmp(oper_states[state], "DOWN") == 0) + color_fprintf(f, COLOR_OPERSTATE_DOWN, "%s ", oper_states[state]); + else + fprintf(f, "%s ", oper_states[state]); + } } } @@ -590,6 +599,88 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n) fprintf(fp, "%s", _SL_); } +int print_linkinfo_brief(const struct sockaddr_nl *who, + struct nlmsghdr *n, void *arg) +{ + FILE *fp = (FILE*)arg; + struct ifinfomsg *ifi = NLMSG_DATA(n); + struct rtattr * tb[IFLA_MAX+1]; + int len = n->nlmsg_len; + char *name; + char buf[32] = { 0, }; + unsigned m_flag = 0; + + if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) + return -1; + + len -= NLMSG_LENGTH(sizeof(*ifi)); + if (len < 0) + return -1; + + if (filter.ifindex && ifi->ifi_index != filter.ifindex) + return -1; + if (filter.up && !(ifi->ifi_flags&IFF_UP)) + return -1; + + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); + if (tb[IFLA_IFNAME] == NULL) { + fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); + } + if (filter.label && + (!filter.family || filter.family == AF_PACKET) && + fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) + return -1; + + if (tb[IFLA_GROUP]) { + int group = *(int*)RTA_DATA(tb[IFLA_GROUP]); + if (filter.group != -1 && group != filter.group) + return -1; + } + + if (n->nlmsg_type == RTM_DELLINK) + fprintf(fp, "Deleted "); + + name = (char *)(tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : ""); + + if (tb[IFLA_LINK]) { + SPRINT_BUF(b1); + int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); + if (iflink == 0) + snprintf(buf, sizeof(buf), "%s@NONE", name); + else { + snprintf(buf, sizeof(buf), + "%s@%s", name, ll_idx_n2a(iflink, b1)); + m_flag = ll_index_to_flags(iflink); + m_flag = !(m_flag & IFF_UP); + } + } else + snprintf(buf, sizeof(buf), "%s", name); + + fprintf(fp, "%-16s ", buf); + + if (tb[IFLA_OPERSTATE]) + print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE])); + + if (filter.family == AF_PACKET) { + SPRINT_BUF(b1); + if (tb[IFLA_ADDRESS]) { + color_fprintf(fp, COLOR_MAC, "%s ", + ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), + RTA_PAYLOAD(tb[IFLA_ADDRESS]), + ifi->ifi_type, + b1, sizeof(b1))); + } + } + + if (filter.family == AF_PACKET) + print_link_flags(fp, ifi->ifi_flags, m_flag); + + if (filter.family == AF_PACKET) + fprintf(fp, "\n"); + fflush(fp); + return 0; +} + int print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { @@ -892,18 +983,20 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, if (n->nlmsg_type == RTM_DELADDR) fprintf(fp, "Deleted "); - if (filter.oneline || filter.flushb) - fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); - if (ifa->ifa_family == AF_INET) - fprintf(fp, " inet "); - else if (ifa->ifa_family == AF_INET6) - fprintf(fp, " inet6 "); - else if (ifa->ifa_family == AF_DECnet) - fprintf(fp, " dnet "); - else if (ifa->ifa_family == AF_IPX) - fprintf(fp, " ipx "); - else - fprintf(fp, " family %d ", ifa->ifa_family); + if (!brief) { + if (filter.oneline || filter.flushb) + fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); + if (ifa->ifa_family == AF_INET) + fprintf(fp, " inet "); + else if (ifa->ifa_family == AF_INET6) + fprintf(fp, " inet6 "); + else if (ifa->ifa_family == AF_DECnet) + fprintf(fp, " dnet "); + else if (ifa->ifa_family == AF_IPX) + fprintf(fp, " ipx "); + else + fprintf(fp, " family %d ", ifa->ifa_family); + } if (rta_tb[IFA_LOCAL]) { if (ifa->ifa_family == AF_INET) @@ -936,6 +1029,9 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, } } + if (brief) + goto brief_exit; + if (rta_tb[IFA_BROADCAST]) { fprintf(fp, "brd %s ", format_host(ifa->ifa_family, @@ -1018,6 +1114,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, } } fprintf(fp, "\n"); +brief_exit: fflush(fp); return 0; } @@ -1078,6 +1175,10 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi, print_addrinfo(NULL, n, fp); } + if (brief) { + fprintf(fp, "\n"); + fflush(fp); + } return 0; } @@ -1539,9 +1640,16 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) for (l = linfo.head; l; l = l->next) { int res = 0; + struct ifinfomsg *ifi = NLMSG_DATA(&l->h); - if (no_link || (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) { - struct ifinfomsg *ifi = NLMSG_DATA(&l->h); + if (brief) { + if (print_linkinfo_brief(NULL, &l->h, stdout) == 0) + if (filter.family != AF_PACKET) + print_selected_addrinfo(ifi, + ainfo.head, + stdout); + } else if (no_link || + (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) { if (filter.family != AF_PACKET) print_selected_addrinfo(ifi, ainfo.head, stdout); diff --git a/ip/iplink.c b/ip/iplink.c index 8bc9f49..633b067 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -823,7 +823,10 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask) if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0) return -2; - print_linkinfo(NULL, &answer.n, stdout); + if (brief) + print_linkinfo_brief(NULL, &answer.n, stdout); + else + print_linkinfo(NULL, &answer.n, stdout); return 0; } diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 68baba7..1896eb6 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -21,7 +21,8 @@ ip-link \- network device configuration \fB\-r\fR[\fIesolve\fR] | \fB\-f\fR[\fIamily\fR] { .BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | " -\fB\-o\fR[\fIneline\fR] } +\fB\-o\fR[\fIneline\fR] | +\fB\-br\fR[\fIief\fR] } .ti -8 .BI "ip link add"