From b3ab1e68e7cb677a0e0fdc09d7736ca50887cffa Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:09 -0800 Subject: [PATCH 1/9] iproute: refactor printing flags Both next hop and route need to decode flags. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index 7616c0d9..024f1cd8 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -347,6 +347,22 @@ static void print_rtax_features(FILE *fp, unsigned int features) fprintf(fp, "0x%x ", of); } +static void print_rt_flags(FILE *fp, unsigned int flags) +{ + if (flags & RTNH_F_DEAD) + fprintf(fp, "dead "); + if (flags & RTNH_F_ONLINK) + fprintf(fp, "onlink "); + if (flags & RTNH_F_PERVASIVE) + fprintf(fp, "pervasive "); + if (flags & RTNH_F_OFFLOAD) + fprintf(fp, "offload "); + if (flags & RTNH_F_LINKDOWN) + fprintf(fp, "linkdown "); + if (flags & RTNH_F_UNRESOLVED) + fprintf(fp, "unresolved "); +} + int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; @@ -478,20 +494,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) } if (tb[RTA_PRIORITY] && filter.metricmask != -1) fprintf(fp, "metric %u ", rta_getattr_u32(tb[RTA_PRIORITY])); - if (r->rtm_flags & RTNH_F_DEAD) - fprintf(fp, "dead "); - if (r->rtm_flags & RTNH_F_ONLINK) - fprintf(fp, "onlink "); - if (r->rtm_flags & RTNH_F_PERVASIVE) - fprintf(fp, "pervasive "); - if (r->rtm_flags & RTNH_F_OFFLOAD) - fprintf(fp, "offload "); - if (r->rtm_flags & RTM_F_NOTIFY) - fprintf(fp, "notify "); - if (r->rtm_flags & RTNH_F_LINKDOWN) - fprintf(fp, "linkdown "); - if (r->rtm_flags & RTNH_F_UNRESOLVED) - fprintf(fp, "unresolved "); + + print_rt_flags(fp, r->rtm_flags); + if (tb[RTA_MARK]) { unsigned int mark = rta_getattr_u32(tb[RTA_MARK]); @@ -728,16 +733,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "weight %d ", nh->rtnh_hops+1); } - if (nh->rtnh_flags & RTNH_F_DEAD) - fprintf(fp, "dead "); - if (nh->rtnh_flags & RTNH_F_ONLINK) - fprintf(fp, "onlink "); - if (nh->rtnh_flags & RTNH_F_PERVASIVE) - fprintf(fp, "pervasive "); - if (nh->rtnh_flags & RTNH_F_OFFLOAD) - fprintf(fp, "offload "); - if (nh->rtnh_flags & RTNH_F_LINKDOWN) - fprintf(fp, "linkdown "); + + print_rt_flags(fp, nh->rtnh_flags); + len -= NLMSG_ALIGN(nh->rtnh_len); nh = RTNH_NEXT(nh); } From 8cfc2d4739b43be2fb9c64d4bb6b9bfdff0a71ad Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:10 -0800 Subject: [PATCH 2/9] iproute: make printing icmpv6 a function Refactor to reduce size of print_route and improve readability. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index 024f1cd8..da6a4fae 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -363,6 +363,25 @@ static void print_rt_flags(FILE *fp, unsigned int flags) fprintf(fp, "unresolved "); } +static void print_rt_pref(FILE *fp, unsigned int pref) +{ + fprintf(fp, "pref "); + + switch (pref) { + case ICMPV6_ROUTER_PREF_LOW: + fprintf(fp, "low"); + break; + case ICMPV6_ROUTER_PREF_MEDIUM: + fprintf(fp, "medium"); + break; + case ICMPV6_ROUTER_PREF_HIGH: + fprintf(fp, "high"); + break; + default: + fprintf(fp, "%u", pref); + } +} + int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; @@ -740,25 +759,10 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) nh = RTNH_NEXT(nh); } } - if (tb[RTA_PREF]) { - unsigned int pref = rta_getattr_u8(tb[RTA_PREF]); - fprintf(fp, "pref "); + if (tb[RTA_PREF]) + print_rt_pref(fp, rta_getattr_u8(tb[RTA_PREF])); - switch (pref) { - case ICMPV6_ROUTER_PREF_LOW: - fprintf(fp, "low"); - break; - case ICMPV6_ROUTER_PREF_MEDIUM: - fprintf(fp, "medium"); - break; - case ICMPV6_ROUTER_PREF_HIGH: - fprintf(fp, "high"); - break; - default: - fprintf(fp, "%u", pref); - } - } if (tb[RTA_TTL_PROPAGATE]) { fprintf(fp, "ttl-propagate "); if (rta_getattr_u8(tb[RTA_TTL_PROPAGATE])) From daf30f6fde11c4c162277305d793c1750f66f6c1 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:11 -0800 Subject: [PATCH 3/9] iproute: make printing IPv4 cache flags a function More refactoring prior to JSON support. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 65 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index da6a4fae..7317bf11 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -382,6 +382,43 @@ static void print_rt_pref(FILE *fp, unsigned int pref) } } +static void print_cache_flags(FILE *fp, __u32 flags) +{ + flags &= ~0xFFFF; + + fprintf(fp, "%s cache ", _SL_); + + if (flags == 0) + return; + + putc('<', fp); + +#define PRTFL(fl, flname) \ + if (flags & RTCF_##fl) { \ + flags &= ~RTCF_##fl; \ + fprintf(fp, "%s%s", flname, flags ? "," : "> "); \ + } + + PRTFL(LOCAL, "local"); + PRTFL(REJECT, "reject"); + PRTFL(MULTICAST, "mc"); + PRTFL(BROADCAST, "brd"); + PRTFL(DNAT, "dst-nat"); + PRTFL(SNAT, "src-nat"); + PRTFL(MASQ, "masq"); + PRTFL(DIRECTDST, "dst-direct"); + PRTFL(DIRECTSRC, "src-direct"); + PRTFL(REDIRECTED, "redirected"); + PRTFL(DOREDIRECT, "redirect"); + PRTFL(FAST, "fastroute"); + PRTFL(NOTIFY, "notify"); + PRTFL(TPROXY, "proxy"); +#undef PRTFL + + if (flags) + fprintf(fp, "%#x> ", flags); +} + int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; @@ -544,33 +581,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) if (tb[RTA_UID]) fprintf(fp, "uid %u ", rta_getattr_u32(tb[RTA_UID])); - if ((r->rtm_flags&RTM_F_CLONED) && r->rtm_family == AF_INET) { - __u32 flags = r->rtm_flags&~0xFFFF; - int first = 1; + if ((r->rtm_flags & RTM_F_CLONED) && r->rtm_family == AF_INET) { + print_cache_flags(fp, r->rtm_flags); - fprintf(fp, "%s cache ", _SL_); - -#define PRTFL(fl, flname) if (flags&RTCF_##fl) { \ - flags &= ~RTCF_##fl; \ - fprintf(fp, "%s" flname "%s", first ? "<" : "", flags ? "," : "> "); \ - first = 0; } - PRTFL(LOCAL, "local"); - PRTFL(REJECT, "reject"); - PRTFL(MULTICAST, "mc"); - PRTFL(BROADCAST, "brd"); - PRTFL(DNAT, "dst-nat"); - PRTFL(SNAT, "src-nat"); - PRTFL(MASQ, "masq"); - PRTFL(DIRECTDST, "dst-direct"); - PRTFL(DIRECTSRC, "src-direct"); - PRTFL(REDIRECTED, "redirected"); - PRTFL(DOREDIRECT, "redirect"); - PRTFL(FAST, "fastroute"); - PRTFL(NOTIFY, "notify"); - PRTFL(TPROXY, "proxy"); - - if (flags) - fprintf(fp, "%s%x> ", first ? "<" : "", flags); if (tb[RTA_CACHEINFO]) { struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]); From 6e41810e1bb9a85461b02d61dc6c5674caa8713d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:12 -0800 Subject: [PATCH 4/9] iproute: refactor cacheinfo printing Make common function for decoding cacheinfo. This code may print more info than old version in some cases. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 78 +++++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index 7317bf11..a5e4c926 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -419,6 +419,31 @@ static void print_cache_flags(FILE *fp, __u32 flags) fprintf(fp, "%#x> ", flags); } +static void print_rta_cacheinfo(FILE *fp, const struct rta_cacheinfo *ci) +{ + static int hz; + + if (!hz) + hz = get_user_hz(); + if (ci->rta_expires != 0) + fprintf(fp, "expires %dsec ", ci->rta_expires/hz); + if (ci->rta_error != 0) + fprintf(fp, "error %d ", ci->rta_error); + if (show_stats) { + if (ci->rta_clntref) + fprintf(fp, "users %d ", ci->rta_clntref); + if (ci->rta_used != 0) + fprintf(fp, "used %d ", ci->rta_used); + if (ci->rta_lastuse != 0) + fprintf(fp, "age %dsec ", ci->rta_lastuse/hz); + } + if (ci->rta_id) + fprintf(fp, "ipid 0x%04x ", ci->rta_id); + if (ci->rta_ts || ci->rta_tsage) + fprintf(fp, "ts 0x%x tsage %dsec ", + ci->rta_ts, ci->rta_tsage); +} + int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; @@ -430,7 +455,6 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) int ret; SPRINT_BUF(b1); - static int hz; if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { fprintf(stderr, "Not a route: %08x %08x %08x\n", @@ -584,56 +608,18 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) if ((r->rtm_flags & RTM_F_CLONED) && r->rtm_family == AF_INET) { print_cache_flags(fp, r->rtm_flags); - if (tb[RTA_CACHEINFO]) { - struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]); + if (tb[RTA_CACHEINFO]) + print_rta_cacheinfo(fp, RTA_DATA(tb[RTA_CACHEINFO])); - if (!hz) - hz = get_user_hz(); - if (ci->rta_expires != 0) - fprintf(fp, "expires %dsec ", ci->rta_expires/hz); - if (ci->rta_error != 0) - fprintf(fp, "error %d ", ci->rta_error); - if (show_stats) { - if (ci->rta_clntref) - fprintf(fp, "users %d ", ci->rta_clntref); - if (ci->rta_used != 0) - fprintf(fp, "used %d ", ci->rta_used); - if (ci->rta_lastuse != 0) - fprintf(fp, "age %dsec ", ci->rta_lastuse/hz); - } - if (ci->rta_id) - fprintf(fp, "ipid 0x%04x ", ci->rta_id); - if (ci->rta_ts || ci->rta_tsage) - fprintf(fp, "ts 0x%x tsage %dsec ", - ci->rta_ts, ci->rta_tsage); - } } else if (r->rtm_family == AF_INET6) { - struct rta_cacheinfo *ci = NULL; + + if (r->rtm_flags & RTM_F_CLONED) + fprintf(fp, "%s cache ", _SL_); if (tb[RTA_CACHEINFO]) - ci = RTA_DATA(tb[RTA_CACHEINFO]); - if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { - if (!hz) - hz = get_user_hz(); - if (r->rtm_flags & RTM_F_CLONED) - fprintf(fp, "%s cache ", _SL_); - if (ci->rta_expires) - fprintf(fp, "expires %dsec ", ci->rta_expires/hz); - if (ci->rta_error != 0) - fprintf(fp, "error %d ", ci->rta_error); - if (show_stats) { - if (ci->rta_clntref) - fprintf(fp, "users %d ", ci->rta_clntref); - if (ci->rta_used != 0) - fprintf(fp, "used %d ", ci->rta_used); - if (ci->rta_lastuse != 0) - fprintf(fp, "age %dsec ", ci->rta_lastuse/hz); - } - } else if (ci) { - if (ci->rta_error != 0) - fprintf(fp, "error %d ", ci->rta_error); - } + print_rta_cacheinfo(fp, RTA_DATA(tb[RTA_CACHEINFO])); } + if (tb[RTA_METRICS]) { int i; unsigned int mxlock = 0; From 968272e791710ca4f0724010c364f0ce0651b180 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:13 -0800 Subject: [PATCH 5/9] iproute: refactor metrics print Make a separate function to improve readability and enable easier JSON conversion. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 117 +++++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index a5e4c926..f93229ca 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -444,6 +444,65 @@ static void print_rta_cacheinfo(FILE *fp, const struct rta_cacheinfo *ci) ci->rta_ts, ci->rta_tsage); } +static void print_rta_metrics(FILE *fp, const struct rtattr *rta) +{ + struct rtattr *mxrta[RTAX_MAX+1]; + unsigned int mxlock = 0; + int i; + + parse_rtattr(mxrta, RTAX_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)); + + if (mxrta[RTAX_LOCK]) + mxlock = rta_getattr_u32(mxrta[RTAX_LOCK]); + + for (i = 2; i <= RTAX_MAX; i++) { + __u32 val = 0U; + + if (mxrta[i] == NULL && !(mxlock & (1 << i))) + continue; + + if (mxrta[i] != NULL && i != RTAX_CC_ALGO) + val = rta_getattr_u32(mxrta[i]); + + if (i == RTAX_HOPLIMIT && (int)val == -1) + continue; + + if (i < sizeof(mx_names)/sizeof(char *) && mx_names[i]) + fprintf(fp, "%s ", mx_names[i]); + else + fprintf(fp, "metric %d ", i); + + if (mxlock & (1<= 1000) + fprintf(fp, "%gs ", val/1e3); + else + fprintf(fp, "%ums ", val); + break; + case RTAX_CC_ALGO: + fprintf(fp, "%s ", rta_getattr_str(mxrta[i])); + break; + } + } +} + int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; @@ -620,63 +679,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) print_rta_cacheinfo(fp, RTA_DATA(tb[RTA_CACHEINFO])); } - if (tb[RTA_METRICS]) { - int i; - unsigned int mxlock = 0; - struct rtattr *mxrta[RTAX_MAX+1]; + if (tb[RTA_METRICS]) + print_rta_metrics(fp, tb[RTA_METRICS]); - parse_rtattr(mxrta, RTAX_MAX, RTA_DATA(tb[RTA_METRICS]), - RTA_PAYLOAD(tb[RTA_METRICS])); - if (mxrta[RTAX_LOCK]) - mxlock = rta_getattr_u32(mxrta[RTAX_LOCK]); - - for (i = 2; i <= RTAX_MAX; i++) { - __u32 val = 0U; - - if (mxrta[i] == NULL && !(mxlock & (1 << i))) - continue; - - if (mxrta[i] != NULL && i != RTAX_CC_ALGO) - val = rta_getattr_u32(mxrta[i]); - - if (i == RTAX_HOPLIMIT && (int)val == -1) - continue; - - if (i < sizeof(mx_names)/sizeof(char *) && mx_names[i]) - fprintf(fp, "%s ", mx_names[i]); - else - fprintf(fp, "metric %d ", i); - - if (mxlock & (1<= 1000) - fprintf(fp, "%gs ", val/1e3); - else - fprintf(fp, "%ums ", val); - break; - case RTAX_CC_ALGO: - fprintf(fp, "%s ", rta_getattr_str(mxrta[i])); - break; - } - } - } if (tb[RTA_IIF] && filter.iifmask != -1) { fprintf(fp, "iif %s ", ll_index_to_name(rta_getattr_u32(tb[RTA_IIF]))); From 5782965a1e95cc558dd49176597aa0a911ae0882 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:14 -0800 Subject: [PATCH 6/9] iproute: refactor printing flow info Use common code for printing flow info. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index f93229ca..1635a9e2 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -444,6 +444,22 @@ static void print_rta_cacheinfo(FILE *fp, const struct rta_cacheinfo *ci) ci->rta_ts, ci->rta_tsage); } +static void print_rta_flow(FILE *fp, const struct rtattr *rta) +{ + __u32 to = rta_getattr_u32(rta); + __u32 from = to >> 16; + SPRINT_BUF(b1); + + to &= 0xFFFF; + fprintf(fp, "realm%s ", from ? "s" : ""); + if (from) { + fprintf(fp, "%s/", + rtnl_rtrealm_n2a(from, b1, sizeof(b1))); + } + fprintf(fp, "%s ", + rtnl_rtrealm_n2a(to, b1, sizeof(b1))); +} + static void print_rta_metrics(FILE *fp, const struct rtattr *rta) { struct rtattr *mxrta[RTAX_MAX+1]; @@ -647,19 +663,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) } } - if (tb[RTA_FLOW] && filter.realmmask != ~0U) { - __u32 to = rta_getattr_u32(tb[RTA_FLOW]); - __u32 from = to>>16; - - to &= 0xFFFF; - fprintf(fp, "realm%s ", from ? "s" : ""); - if (from) { - fprintf(fp, "%s/", - rtnl_rtrealm_n2a(from, b1, sizeof(b1))); - } - fprintf(fp, "%s ", - rtnl_rtrealm_n2a(to, b1, sizeof(b1))); - } + if (tb[RTA_FLOW] && filter.realmmask != ~0U) + print_rta_flow(fp, tb[RTA_FLOW]); if (tb[RTA_UID]) fprintf(fp, "uid %u ", rta_getattr_u32(tb[RTA_UID])); @@ -731,19 +736,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) family_name(via->rtvia_family), format_host(via->rtvia_family, len, via->rtvia_addr)); } - if (tb[RTA_FLOW]) { - __u32 to = rta_getattr_u32(tb[RTA_FLOW]); - __u32 from = to>>16; - - to &= 0xFFFF; - fprintf(fp, "realm%s ", from ? "s" : ""); - if (from) { - fprintf(fp, "%s/", - rtnl_rtrealm_n2a(from, b1, sizeof(b1))); - } - fprintf(fp, "%s ", - rtnl_rtrealm_n2a(to, b1, sizeof(b1))); - } + if (tb[RTA_FLOW]) + print_rta_flow(fp, tb[RTA_FLOW]); } if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) { fprintf(fp, "%s", ll_index_to_name(nh->rtnh_ifindex)); From a3484a9f209b189e2854fcbc7e77203a6c172bc3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:15 -0800 Subject: [PATCH 7/9] iproute: refactor newdst, gateway and via printing Since these fields are printed in both route and multipath case; avoid duplicating code. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 73 ++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index 1635a9e2..74216e73 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -460,6 +460,32 @@ static void print_rta_flow(FILE *fp, const struct rtattr *rta) rtnl_rtrealm_n2a(to, b1, sizeof(b1))); } +static void print_rta_newdst(FILE *fp, const struct rtmsg *r, + const struct rtattr *rta) +{ + const char *newdst = format_host_rta(r->rtm_family, rta); + + fprintf(fp, "as to %s ", newdst); +} + +static void print_rta_gateway(FILE *fp, const struct rtmsg *r, + const struct rtattr *rta) +{ + const char *gateway = format_host_rta(r->rtm_family, rta); + + fprintf(fp, "via %s ", gateway); +} + +static void print_rta_via(FILE *fp, const struct rtattr *rta) +{ + const struct rtvia *via = RTA_DATA(rta); + size_t len = RTA_PAYLOAD(rta); + + fprintf(fp, "via %s %s ", + family_name(via->rtvia_family), + format_host(via->rtvia_family, len, via->rtvia_addr)); +} + static void print_rta_metrics(FILE *fp, const struct rtattr *rta) { struct rtattr *mxrta[RTAX_MAX+1]; @@ -604,10 +630,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) } else if (r->rtm_src_len) { fprintf(fp, "from 0/%u ", r->rtm_src_len); } - if (tb[RTA_NEWDST]) { - fprintf(fp, "as to %s ", - format_host_rta(r->rtm_family, tb[RTA_NEWDST])); - } + + if (tb[RTA_NEWDST]) + print_rta_newdst(fp, r, tb[RTA_NEWDST]); if (tb[RTA_ENCAP]) lwt_print_encap(fp, tb[RTA_ENCAP_TYPE], tb[RTA_ENCAP]); @@ -617,18 +642,12 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1))); } - if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) { - fprintf(fp, "via %s ", - format_host_rta(r->rtm_family, tb[RTA_GATEWAY])); - } - if (tb[RTA_VIA]) { - size_t len = RTA_PAYLOAD(tb[RTA_VIA]) - 2; - struct rtvia *via = RTA_DATA(tb[RTA_VIA]); + if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) + print_rta_gateway(fp, r, tb[RTA_GATEWAY]); + + if (tb[RTA_VIA]) + print_rta_via(fp, tb[RTA_VIA]); - fprintf(fp, "via %s %s ", - family_name(via->rtvia_family), - format_host(via->rtvia_family, len, via->rtvia_addr)); - } if (tb[RTA_OIF] && filter.oifmask != -1) fprintf(fp, "dev %s ", ll_index_to_name(rta_getattr_u32(tb[RTA_OIF]))); @@ -718,24 +737,12 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) lwt_print_encap(fp, tb[RTA_ENCAP_TYPE], tb[RTA_ENCAP]); - if (tb[RTA_NEWDST]) { - fprintf(fp, "as to %s ", - format_host_rta(r->rtm_family, - tb[RTA_NEWDST])); - } - if (tb[RTA_GATEWAY]) { - fprintf(fp, "via %s ", - format_host_rta(r->rtm_family, - tb[RTA_GATEWAY])); - } - if (tb[RTA_VIA]) { - size_t len = RTA_PAYLOAD(tb[RTA_VIA]) - 2; - struct rtvia *via = RTA_DATA(tb[RTA_VIA]); - - fprintf(fp, "via %s %s ", - family_name(via->rtvia_family), - format_host(via->rtvia_family, len, via->rtvia_addr)); - } + if (tb[RTA_NEWDST]) + print_rta_newdst(fp, r, tb[RTA_NEWDST]); + if (tb[RTA_GATEWAY]) + print_rta_gateway(fp, r, tb[RTA_GATEWAY]); + if (tb[RTA_VIA]) + print_rta_via(fp, tb[RTA_VIA]); if (tb[RTA_FLOW]) print_rta_flow(fp, tb[RTA_FLOW]); } From f48e14880a0e5601e6859eba391bb909e171b78c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:16 -0800 Subject: [PATCH 8/9] iproute: refactor multipath print Make printing of multipath attributes a function to improve readability. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 116 ++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index 74216e73..c9139bf6 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -545,6 +545,67 @@ static void print_rta_metrics(FILE *fp, const struct rtattr *rta) } } +static void print_rta_multipath(FILE *fp, const struct rtmsg *r, + struct rtattr *rta) +{ + const struct rtnexthop *nh = RTA_DATA(rta); + int len = RTA_PAYLOAD(rta); + int first = 1; + + while (len > sizeof(*nh)) { + struct rtattr *tb[RTA_MAX + 1]; + + if (nh->rtnh_len > len) + break; + + if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) { + if (first) { + fprintf(fp, "Oifs: "); + first = 0; + } else { + fprintf(fp, " "); + } + } else + fprintf(fp, "%s\tnexthop ", _SL_); + + if (nh->rtnh_len > sizeof(*nh)) { + parse_rtattr(tb, RTA_MAX, RTNH_DATA(nh), + nh->rtnh_len - sizeof(*nh)); + + if (tb[RTA_ENCAP]) + lwt_print_encap(fp, + tb[RTA_ENCAP_TYPE], + tb[RTA_ENCAP]); + if (tb[RTA_NEWDST]) + print_rta_newdst(fp, r, tb[RTA_NEWDST]); + if (tb[RTA_GATEWAY]) + print_rta_gateway(fp, r, tb[RTA_GATEWAY]); + if (tb[RTA_VIA]) + print_rta_via(fp, tb[RTA_VIA]); + if (tb[RTA_FLOW]) + print_rta_flow(fp, tb[RTA_FLOW]); + } + + if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) { + fprintf(fp, "%s", ll_index_to_name(nh->rtnh_ifindex)); + if (nh->rtnh_hops != 1) + fprintf(fp, "(ttl>%d)", nh->rtnh_hops); + fprintf(fp, " "); + } else { + fprintf(fp, "dev %s ", + ll_index_to_name(nh->rtnh_ifindex)); + if (r->rtm_family != AF_MPLS) + fprintf(fp, "weight %d ", + nh->rtnh_hops+1); + } + + print_rt_flags(fp, nh->rtnh_flags); + + len -= NLMSG_ALIGN(nh->rtnh_len); + nh = RTNH_NEXT(nh); + } +} + int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; @@ -710,60 +771,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "iif %s ", ll_index_to_name(rta_getattr_u32(tb[RTA_IIF]))); } - if (tb[RTA_MULTIPATH]) { - struct rtnexthop *nh = RTA_DATA(tb[RTA_MULTIPATH]); - int first = 1; - len = RTA_PAYLOAD(tb[RTA_MULTIPATH]); - - for (;;) { - if (len < sizeof(*nh)) - break; - if (nh->rtnh_len > len) - break; - if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) { - if (first) { - fprintf(fp, "Oifs: "); - first = 0; - } else { - fprintf(fp, " "); - } - } else - fprintf(fp, "%s\tnexthop ", _SL_); - if (nh->rtnh_len > sizeof(*nh)) { - parse_rtattr(tb, RTA_MAX, RTNH_DATA(nh), nh->rtnh_len - sizeof(*nh)); - - if (tb[RTA_ENCAP]) - lwt_print_encap(fp, - tb[RTA_ENCAP_TYPE], - tb[RTA_ENCAP]); - if (tb[RTA_NEWDST]) - print_rta_newdst(fp, r, tb[RTA_NEWDST]); - if (tb[RTA_GATEWAY]) - print_rta_gateway(fp, r, tb[RTA_GATEWAY]); - if (tb[RTA_VIA]) - print_rta_via(fp, tb[RTA_VIA]); - if (tb[RTA_FLOW]) - print_rta_flow(fp, tb[RTA_FLOW]); - } - if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) { - fprintf(fp, "%s", ll_index_to_name(nh->rtnh_ifindex)); - if (nh->rtnh_hops != 1) - fprintf(fp, "(ttl>%d)", nh->rtnh_hops); - fprintf(fp, " "); - } else { - fprintf(fp, "dev %s ", ll_index_to_name(nh->rtnh_ifindex)); - if (r->rtm_family != AF_MPLS) - fprintf(fp, "weight %d ", - nh->rtnh_hops+1); - } - - print_rt_flags(fp, nh->rtnh_flags); - - len -= NLMSG_ALIGN(nh->rtnh_len); - nh = RTNH_NEXT(nh); - } - } + if (tb[RTA_MULTIPATH]) + print_rta_multipath(fp, r, tb[RTA_MULTIPATH]); if (tb[RTA_PREF]) print_rt_pref(fp, rta_getattr_u8(tb[RTA_PREF])); From 1506d8d3f8f1c62dacdd316c5ddac66a63e3cc15 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Feb 2018 09:10:17 -0800 Subject: [PATCH 9/9] iproute: refactor printing of interface For JSON and colorization, make common code a function. Signed-off-by: Stephen Hemminger Signed-off-by: David Ahern --- ip/iproute.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ip/iproute.c b/ip/iproute.c index c9139bf6..91d2b1a6 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -382,6 +382,14 @@ static void print_rt_pref(FILE *fp, unsigned int pref) } } +static void print_rta_if(FILE *fp, const struct rtattr *rta, + const char *prefix) +{ + const char *ifname = ll_index_to_name(rta_getattr_u32(rta)); + + fprintf(fp, "%s %s ", prefix, ifname); +} + static void print_cache_flags(FILE *fp, __u32 flags) { flags &= ~0xFFFF; @@ -710,7 +718,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) print_rta_via(fp, tb[RTA_VIA]); if (tb[RTA_OIF] && filter.oifmask != -1) - fprintf(fp, "dev %s ", ll_index_to_name(rta_getattr_u32(tb[RTA_OIF]))); + print_rta_if(fp, tb[RTA_OIF], "dev"); if (table && (table != RT_TABLE_MAIN || show_details > 0) && !filter.tb) fprintf(fp, "table %s ", rtnl_rttable_n2a(table, b1, sizeof(b1))); @@ -767,10 +775,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) if (tb[RTA_METRICS]) print_rta_metrics(fp, tb[RTA_METRICS]); - if (tb[RTA_IIF] && filter.iifmask != -1) { - fprintf(fp, "iif %s ", - ll_index_to_name(rta_getattr_u32(tb[RTA_IIF]))); - } + if (tb[RTA_IIF] && filter.iifmask != -1) + print_rta_if(fp, tb[RTA_IIF], "iif"); if (tb[RTA_MULTIPATH]) print_rta_multipath(fp, r, tb[RTA_MULTIPATH]);