|
|
07a51b |
From 65d5e933e5162c3464857ee233a2f20e778ee1b6 Mon Sep 17 00:00:00 2001
|
|
|
07a51b |
From: Andrea Claudi <aclaudi@redhat.com>
|
|
|
07a51b |
Date: Thu, 30 Apr 2020 12:35:47 +0200
|
|
|
07a51b |
Subject: [PATCH] ip: fix ip route show json output for multipath nexthops
|
|
|
07a51b |
|
|
|
07a51b |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1738633
|
|
|
07a51b |
Upstream Status: iproute2.git commit 4ecefff3cf250
|
|
|
07a51b |
|
|
|
07a51b |
commit 4ecefff3cf250c1e4499dff14c80ed38bec6d7de
|
|
|
07a51b |
Author: Julien Fortin <julien@cumulusnetworks.com>
|
|
|
07a51b |
Date: Thu Sep 26 17:29:34 2019 +0200
|
|
|
07a51b |
|
|
|
07a51b |
ip: fix ip route show json output for multipath nexthops
|
|
|
07a51b |
|
|
|
07a51b |
print_rta_multipath doesn't support JSON output:
|
|
|
07a51b |
|
|
|
07a51b |
{
|
|
|
07a51b |
"dst":"27.0.0.13",
|
|
|
07a51b |
"protocol":"bgp",
|
|
|
07a51b |
"metric":20,
|
|
|
07a51b |
"flags":[],
|
|
|
07a51b |
"gateway":"169.254.0.1"dev uplink-1 weight 1 ,
|
|
|
07a51b |
"flags":["onlink"],
|
|
|
07a51b |
"gateway":"169.254.0.1"dev uplink-2 weight 1 ,
|
|
|
07a51b |
"flags":["onlink"]
|
|
|
07a51b |
},
|
|
|
07a51b |
|
|
|
07a51b |
since RTA_MULTIPATH has nested objects we should print them
|
|
|
07a51b |
in a json array.
|
|
|
07a51b |
|
|
|
07a51b |
With the path we have the following output:
|
|
|
07a51b |
|
|
|
07a51b |
{
|
|
|
07a51b |
"flags": [],
|
|
|
07a51b |
"dst": "36.0.0.13",
|
|
|
07a51b |
"protocol": "bgp",
|
|
|
07a51b |
"metric": 20,
|
|
|
07a51b |
"nexthops": [
|
|
|
07a51b |
{
|
|
|
07a51b |
"weight": 1,
|
|
|
07a51b |
"flags": [
|
|
|
07a51b |
"onlink"
|
|
|
07a51b |
],
|
|
|
07a51b |
"gateway": "169.254.0.1",
|
|
|
07a51b |
"dev": "uplink-1"
|
|
|
07a51b |
},
|
|
|
07a51b |
{
|
|
|
07a51b |
"weight": 1,
|
|
|
07a51b |
"flags": [
|
|
|
07a51b |
"onlink"
|
|
|
07a51b |
],
|
|
|
07a51b |
"gateway": "169.254.0.1",
|
|
|
07a51b |
"dev": "uplink-2"
|
|
|
07a51b |
}
|
|
|
07a51b |
]
|
|
|
07a51b |
}
|
|
|
07a51b |
|
|
|
07a51b |
Fixes: 663c3cb23103f4 ("iproute: implement JSON and color output")
|
|
|
07a51b |
|
|
|
07a51b |
Signed-off-by: Julien Fortin <julien@cumulusnetworks.com>
|
|
|
07a51b |
Signed-off-by: David Ahern <dsahern@gmail.com>
|
|
|
07a51b |
---
|
|
|
07a51b |
ip/iproute.c | 46 ++++++++++++++++++++++++++++------------------
|
|
|
07a51b |
1 file changed, 28 insertions(+), 18 deletions(-)
|
|
|
07a51b |
|
|
|
07a51b |
diff --git a/ip/iproute.c b/ip/iproute.c
|
|
|
07a51b |
index a453385113cb9..32bb52df250c2 100644
|
|
|
07a51b |
--- a/ip/iproute.c
|
|
|
07a51b |
+++ b/ip/iproute.c
|
|
|
07a51b |
@@ -649,24 +649,26 @@ static void print_rta_multipath(FILE *fp, const struct rtmsg *r,
|
|
|
07a51b |
int len = RTA_PAYLOAD(rta);
|
|
|
07a51b |
int first = 1;
|
|
|
07a51b |
|
|
|
07a51b |
+ open_json_array(PRINT_JSON, "nexthops");
|
|
|
07a51b |
+
|
|
|
07a51b |
while (len >= sizeof(*nh)) {
|
|
|
07a51b |
struct rtattr *tb[RTA_MAX + 1];
|
|
|
07a51b |
|
|
|
07a51b |
if (nh->rtnh_len > len)
|
|
|
07a51b |
break;
|
|
|
07a51b |
|
|
|
07a51b |
- if (!is_json_context()) {
|
|
|
07a51b |
- if ((r->rtm_flags & RTM_F_CLONED) &&
|
|
|
07a51b |
- r->rtm_type == RTN_MULTICAST) {
|
|
|
07a51b |
- if (first) {
|
|
|
07a51b |
- fprintf(fp, "Oifs: ");
|
|
|
07a51b |
- first = 0;
|
|
|
07a51b |
- } else {
|
|
|
07a51b |
- fprintf(fp, " ");
|
|
|
07a51b |
- }
|
|
|
07a51b |
- } else
|
|
|
07a51b |
- fprintf(fp, "%s\tnexthop ", _SL_);
|
|
|
07a51b |
- }
|
|
|
07a51b |
+ open_json_object(NULL);
|
|
|
07a51b |
+
|
|
|
07a51b |
+ if ((r->rtm_flags & RTM_F_CLONED) &&
|
|
|
07a51b |
+ r->rtm_type == RTN_MULTICAST) {
|
|
|
07a51b |
+ if (first) {
|
|
|
07a51b |
+ print_string(PRINT_FP, NULL, "Oifs: ", NULL);
|
|
|
07a51b |
+ first = 0;
|
|
|
07a51b |
+ } else {
|
|
|
07a51b |
+ print_string(PRINT_FP, NULL, " ", NULL);
|
|
|
07a51b |
+ }
|
|
|
07a51b |
+ } else
|
|
|
07a51b |
+ print_string(PRINT_FP, NULL, "%s\tnexthop ", _SL_);
|
|
|
07a51b |
|
|
|
07a51b |
if (nh->rtnh_len > sizeof(*nh)) {
|
|
|
07a51b |
parse_rtattr(tb, RTA_MAX, RTNH_DATA(nh),
|
|
|
07a51b |
@@ -689,22 +691,30 @@ static void print_rta_multipath(FILE *fp, const struct rtmsg *r,
|
|
|
07a51b |
|
|
|
07a51b |
if ((r->rtm_flags & RTM_F_CLONED) &&
|
|
|
07a51b |
r->rtm_type == RTN_MULTICAST) {
|
|
|
07a51b |
- fprintf(fp, "%s", ll_index_to_name(nh->rtnh_ifindex));
|
|
|
07a51b |
+ print_string(PRINT_ANY, "dev",
|
|
|
07a51b |
+ "%s", ll_index_to_name(nh->rtnh_ifindex));
|
|
|
07a51b |
+
|
|
|
07a51b |
if (nh->rtnh_hops != 1)
|
|
|
07a51b |
- fprintf(fp, "(ttl>%d)", nh->rtnh_hops);
|
|
|
07a51b |
- fprintf(fp, " ");
|
|
|
07a51b |
+ print_int(PRINT_ANY, "ttl", "(ttl>%d)", nh->rtnh_hops);
|
|
|
07a51b |
+
|
|
|
07a51b |
+ print_string(PRINT_FP, NULL, " ", NULL);
|
|
|
07a51b |
} else {
|
|
|
07a51b |
- fprintf(fp, "dev %s ", ll_index_to_name(nh->rtnh_ifindex));
|
|
|
07a51b |
+ print_string(PRINT_ANY, "dev",
|
|
|
07a51b |
+ "dev %s ", ll_index_to_name(nh->rtnh_ifindex));
|
|
|
07a51b |
+
|
|
|
07a51b |
if (r->rtm_family != AF_MPLS)
|
|
|
07a51b |
- fprintf(fp, "weight %d ",
|
|
|
07a51b |
- nh->rtnh_hops+1);
|
|
|
07a51b |
+ print_int(PRINT_ANY, "weight",
|
|
|
07a51b |
+ "weight %d ", nh->rtnh_hops + 1);
|
|
|
07a51b |
}
|
|
|
07a51b |
|
|
|
07a51b |
print_rt_flags(fp, nh->rtnh_flags);
|
|
|
07a51b |
|
|
|
07a51b |
len -= NLMSG_ALIGN(nh->rtnh_len);
|
|
|
07a51b |
nh = RTNH_NEXT(nh);
|
|
|
07a51b |
+
|
|
|
07a51b |
+ close_json_object();
|
|
|
07a51b |
}
|
|
|
07a51b |
+ close_json_array(PRINT_JSON, NULL);
|
|
|
07a51b |
}
|
|
|
07a51b |
|
|
|
07a51b |
int print_route(struct nlmsghdr *n, void *arg)
|
|
|
07a51b |
--
|
|
|
07a51b |
2.25.4
|
|
|
07a51b |
|