]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
add support for brief output for link and addresses
authorAndy Gospodarek <gospo@cumulusnetworks.com>
Fri, 28 Aug 2015 17:45:41 +0000 (13:45 -0400)
committerStephen Hemminger <shemming@brocade.com>
Mon, 31 Aug 2015 23:24:10 +0000 (16:24 -0700)
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 <LOOPBACK,UP,LOWER_UP>
p2p1             UP             08:00:27:ee:0b:3b <BROADCAST,MULTICAST,UP,LOWER_UP>
p7p1             UP             08:00:27:9d:62:9f <BROADCAST,MULTICAST,UP,LOWER_UP>
p8p1             DOWN           08:00:27:dc:d8:ca <NO-CARRIER,BROADCAST,MULTICAST,UP>
p9p1             UP             08:00:27:76:d9:75 <BROADCAST,MULTICAST,UP,LOWER_UP>
p7p1.100@p7p1    UP             08:00:27:9d:62:9f <BROADCAST,MULTICAST,UP,LOWER_UP>

$ 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 <gospo@cumulusnetworks.com>
include/utils.h
ip/ip.c
ip/ip_common.h
ip/ipaddress.c
ip/iplink.c
man/man8/ip-link.8.in

index 0c57ccdc7de5594ca41c9b7ec6b9cbf39855d519..f77edeb0f8845fec65ecc7daffebb6cf3cb28e8e 100644 (file)
@@ -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 e75447e1bdfd0dda9086d1c43872a153cbccfa50..eea00b822088ef5accb6a3e25eb11027d09ac527 100644 (file)
--- 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;
 
index f120f5b9714381e1a660557529db9180aef08eaf..f74face6942162364dfaa8943e56a0dc8ca25f53 100644 (file)
@@ -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);
index 177b65a9b97f4b1bfffafb803fe752e530df6e4e..5dad5d6f9df076eea10e60e02463f01073844832 100644 (file)
@@ -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]) : "<nil>");
+
+       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)
 {
@@ -887,18 +978,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)
@@ -931,6 +1024,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,
@@ -1013,6 +1109,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
                }
        }
        fprintf(fp, "\n");
+brief_exit:
        fflush(fp);
        return 0;
 }
@@ -1073,6 +1170,10 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi,
 
                print_addrinfo(NULL, n, fp);
        }
+       if (brief) {
+               fprintf(fp, "\n");
+               fflush(fp);
+       }
        return 0;
 }
 
@@ -1534,9 +1635,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);
index cdb3f73e499cefcfdb6f466400f0cf8988a838ec..5361c2f9fafcce04cba04ae8b616b83213674525 100644 (file)
@@ -831,7 +831,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;
 }
index 2283b710d0b19770b62def7949fecfbd0dbef6fb..81c48920b885851b249204a70496906e77cebf56 100644 (file)
@@ -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"