There is at least three places implementing same things: two in
ipaddress.c print_linkinfo() & print_linkinfo_brief() and one in
bridge/link.c.

They are diverge from each other very little: bridge/link.c does not
support JSON output at the moment and print_linkinfo_brief() does not
handle IFLA_LINK_NETNS case.

Introduce and use print_name_and_link() routine to handle name@link
output in all possible variations; respect IFLA_LINK_NETNS attribute to
handle case when link is in different namespace; use ll_idx_n2a() for
interface name instead of "<nil>" to share logic with other code (e.g.
ll_name_to_index() and ll_index_to_name()) supporting such template.

Signed-off-by: Serhey Popovych <serhe.popov...@gmail.com>
---
 bridge/link.c   |   13 +++----------
 include/utils.h |    4 ++++
 ip/ipaddress.c  |   44 ++------------------------------------------
 lib/utils.c     |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/bridge/link.c b/bridge/link.c
index a11cbb1..90c9734 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -125,20 +125,13 @@ int print_linkinfo(const struct sockaddr_nl *who,
        if (n->nlmsg_type == RTM_DELLINK)
                fprintf(fp, "Deleted ");
 
-       fprintf(fp, "%d: %s ", ifi->ifi_index,
-               tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
+       fprintf(fp, "%d: ", ifi->ifi_index);
+
+       print_name_and_link("%s: ", COLOR_NONE, name, tb);
 
        if (tb[IFLA_OPERSTATE])
                print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
 
-       if (tb[IFLA_LINK]) {
-               int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-
-               fprintf(fp, "@%s: ",
-                       iflink ? ll_index_to_name(iflink) : "NONE");
-       } else
-               fprintf(fp, ": ");
-
        print_link_flags(fp, ifi->ifi_flags);
 
        if (tb[IFLA_MTU])
diff --git a/include/utils.h b/include/utils.h
index 84ca873..75ddb4a 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -12,6 +12,7 @@
 #include "libnetlink.h"
 #include "ll_map.h"
 #include "rtm_map.h"
+#include "json_print.h"
 
 extern int preferred_family;
 extern int human_readable;
@@ -250,6 +251,9 @@ void print_escape_buf(const __u8 *buf, size_t len, const 
char *escape);
 int print_timestamp(FILE *fp);
 void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n);
 
+unsigned int print_name_and_link(const char *fmt, enum color_attr color,
+                                const char *name, struct rtattr *tb[]);
+
 #define BIT(nr)                 (1UL << (nr))
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 670d8e0..e14a59e 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -760,7 +760,6 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
        struct rtattr *tb[IFLA_MAX+1];
        int len = n->nlmsg_len;
        const char *name;
-       char buf[32] = { 0, };
        unsigned int m_flag = 0;
 
        if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
@@ -810,25 +809,7 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
        if (n->nlmsg_type == RTM_DELLINK)
                print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
-       if (tb[IFLA_LINK]) {
-               int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-
-               if (iflink == 0) {
-                       snprintf(buf, sizeof(buf), "%s@NONE", name);
-                       print_null(PRINT_JSON, "link", NULL, NULL);
-               } else {
-                       const char *link = ll_index_to_name(iflink);
-
-                       print_string(PRINT_JSON, "link", NULL, link);
-                       snprintf(buf, sizeof(buf), "%s@%s", name, link);
-                       m_flag = ll_index_to_flags(iflink);
-                       m_flag = !(m_flag & IFF_UP);
-               }
-       } else
-               snprintf(buf, sizeof(buf), "%s", name);
-
-       print_string(PRINT_FP, NULL, "%-16s ", buf);
-       print_string(PRINT_JSON, "ifname", NULL, name);
+       m_flag = print_name_and_link("%-16s ", COLOR_NONE, name, tb);
 
        if (tb[IFLA_OPERSTATE])
                print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
@@ -936,29 +917,8 @@ int print_linkinfo(const struct sockaddr_nl *who,
                print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
        print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
-       print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname", "%s", name);
-
-       if (tb[IFLA_LINK]) {
-               int iflink = rta_getattr_u32(tb[IFLA_LINK]);
 
-               if (iflink == 0)
-                       print_null(PRINT_ANY, "link", "@%s: ", "NONE");
-               else {
-                       if (tb[IFLA_LINK_NETNSID])
-                               print_int(PRINT_ANY,
-                                         "link_index", "@if%d: ", iflink);
-                       else {
-                               print_string(PRINT_ANY,
-                                            "link",
-                                            "@%s: ",
-                                            ll_index_to_name(iflink));
-                               m_flag = ll_index_to_flags(iflink);
-                               m_flag = !(m_flag & IFF_UP);
-                       }
-               }
-       } else {
-               print_string(PRINT_FP, NULL, ": ", NULL);
-       }
+       m_flag = print_name_and_link("%s: ", COLOR_IFNAME, name, tb);
        print_link_flags(fp, ifi->ifi_flags, m_flag);
 
        if (tb[IFLA_MTU])
diff --git a/lib/utils.c b/lib/utils.c
index 572d42a..0f9523c 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -33,6 +33,7 @@
 
 #include "rt_names.h"
 #include "utils.h"
+#include "ll_map.h"
 #include "namespace.h"
 
 int resolve_hosts;
@@ -1260,6 +1261,54 @@ int print_timestamp(FILE *fp)
        return 0;
 }
 
+unsigned int print_name_and_link(const char *fmt, enum color_attr color,
+                                const char *name, struct rtattr *tb[])
+{
+       const char *link = NULL;
+       unsigned int m_flag = 0;
+       SPRINT_BUF(b1);
+
+       if (tb[IFLA_LINK]) {
+               int iflink = rta_getattr_u32(tb[IFLA_LINK]);
+
+               if (iflink) {
+                       if (tb[IFLA_LINK_NETNSID]) {
+                               if (is_json_context()) {
+                                       print_int(PRINT_JSON,
+                                                 "link_index", NULL, iflink);
+                               } else {
+                                       link = ll_idx_n2a(iflink);
+                               }
+                       } else {
+                               link = ll_index_to_name(iflink);
+
+                               if (is_json_context()) {
+                                       print_string(PRINT_JSON,
+                                                    "link", NULL, link);
+                                       link = NULL;
+                               }
+
+                               m_flag = ll_index_to_flags(iflink);
+                               m_flag = !(m_flag & IFF_UP);
+                       }
+               } else {
+                       if (is_json_context())
+                               print_null(PRINT_JSON, "link", NULL, NULL);
+                       else
+                               link = "NONE";
+               }
+
+               if (link) {
+                       snprintf(b1, sizeof(b1), "%s@%s", name, link);
+                       name = b1;
+               }
+       }
+
+       print_color_string(PRINT_ANY, color, "ifname", fmt, name);
+
+       return m_flag;
+}
+
 int cmdlineno;
 
 /* Like glibc getline but handle continuation lines and comments */
-- 
1.7.10.4

Reply via email to