From patchwork Mon Aug 24 20:41:16 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andy Gospodarek X-Patchwork-Id: 510316 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 E90BB1401F6 for ; Tue, 25 Aug 2015 06:52:02 +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=M45ojx1r; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751734AbbHXUvx (ORCPT ); Mon, 24 Aug 2015 16:51:53 -0400 Received: from mail-pa0-f48.google.com ([209.85.220.48]:32815 "EHLO mail-pa0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750942AbbHXUvw (ORCPT ); Mon, 24 Aug 2015 16:51:52 -0400 Received: by pacti10 with SMTP id ti10so31973589pac.0 for ; Mon, 24 Aug 2015 13:51:51 -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=jsY0uGR6tl6ZExLgyNrKsI/iR5EtSC5lWDPsHcIvCqE=; b=M45ojx1r+G04SbFMWpVegM8amnF3Z0e4wpig17ZWsdYpi12lWtFFl19Jrm7E6+bpTI wJ71Puj/cXuhOeaP7uQ0RMeiE/dYqH4k46SLnhTdlVZPZ+wsJXoqU8cSrDgpht4oqhtS QxuArO2L7jbHHnFKIyoRuCjZZ5IELIhydLknY= 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=jsY0uGR6tl6ZExLgyNrKsI/iR5EtSC5lWDPsHcIvCqE=; b=X4McJWYEP9T8nAINTUS/hPsL3uxMZieQT7LHhQiQ0HBh2OhMJ0blMdXkkn8PFp5Q0w i6OumzvmYKc2QER8KuofP1eaTQTurWIP59h6GjN2PWbIIA8N/JmNi5FwZljr1i4EXfeB ybwso1ygBEsokyrO6vyMLgodOjeUQE+rqZDRRTZTYoJa8g0nPri7eXzdLPsjTR8ffN3O mhHxOl4Tco0DnAsi421jpS0g8oGf8Y9BOfH8MPtQeE4/+A6pHAtXmq6I7wG00L7CcqS3 BRgFhaF6ZcSOCrdf92bTFnI0wwLgWNcG1Ozdl6cKhYS3dXXU3J0YBz2uSR2izSUGUHCL 7uNg== X-Gm-Message-State: ALoCoQn6w/Vong9CwgUfs1oY7h1jbAGmez0Zo5kbFvLRdkRGZw+4ViWCG92U+rBUbqSskp+rXMmw X-Received: by 10.68.65.16 with SMTP id t16mr49630296pbs.48.1440449511460; Mon, 24 Aug 2015 13:51:51 -0700 (PDT) Received: from fedora-devel.cumulusnetworks.com ([216.129.126.126]) by smtp.googlemail.com with ESMTPSA id em1sm18401513pbd.42.2015.08.24.13.51.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Aug 2015 13:51:50 -0700 (PDT) From: Andy Gospodarek To: netdev@vger.kernel.org Cc: Stephen Hemminger , Andy Gospodarek Subject: [PATCH iproute2] add support for brief output for link and addresses Date: Mon, 24 Aug 2015 16:41:16 -0400 Message-Id: <1440448876-23950-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 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 p7p1 UP 70.0.0.1/24 p8p1 DOWN 80.0.0.1/24 p7p1.100@p7p1 UP 200.0.0.1/24 $ ip -br -6 addr show lo UNKNOWN ::1/128 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 Signed-off-by: Andy Gospodarek --- include/utils.h | 1 + ip/ip.c | 5 +- ip/ip_common.h | 3 + ip/ipaddress.c | 149 ++++++++++++++++++++++++++++++++++++++++++-------- ip/iplink.c | 5 +- man/man8/ip-link.8.in | 3 +- 6 files changed, 141 insertions(+), 25 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..84b453f 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -125,7 +125,10 @@ static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown) fprintf(fp, "%x", flags); if (mdown) fprintf(fp, ",M-DOWN"); - fprintf(fp, "> "); + if (brief) + fprintf(fp, ">"); + else + fprintf(fp, "> "); } static const char *oper_states[] = { @@ -138,13 +141,17 @@ 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) { + fprintf(f, "%-7s ", 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 +597,87 @@ 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]) { + fprintf(fp, "%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 +980,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 +1026,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 +1111,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, } } fprintf(fp, "\n"); +brief_exit: fflush(fp); return 0; } @@ -1078,6 +1172,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 +1637,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 2f689ed..8732ea7 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"