summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2023-02-17 20:24:33 +0200
committerGitHub <noreply@github.com>2023-02-17 20:24:33 +0200
commit5ef2911d230d4729364ed8178d7de5764a5c32e4 (patch)
treeca7ff1596c516667560e8578cc5d761211f891d1
parent8383d53e43dfe7313783700bc2ed0ec823224bf1 (diff)
parent04705e4829d5690519781179846bd694ac2120b9 (diff)
Merge pull request #12791 from taspelund/loc_rib_json_fix
bgpd: fix 'json detail' output structure
-rw-r--r--bgpd/bgp_evpn_vty.c12
-rw-r--r--bgpd/bgp_route.c84
-rw-r--r--bgpd/bgp_route.h3
-rw-r--r--tests/topotests/bgp_aigp/test_bgp_aigp.py52
-rw-r--r--tests/topotests/bgp_community_alias/test_bgp-community-alias.py16
-rw-r--r--tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py72
-rw-r--r--tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py38
7 files changed, 158 insertions, 119 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index ceff7a46c4..33c202c3d7 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -2472,7 +2472,7 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
/* Prefix and num paths displayed once per prefix. */
route_vty_out_detail_header(vty, bgp, dest, bgp_dest_get_prefix(dest),
- NULL, afi, safi, json);
+ NULL, afi, safi, json, false);
/* Display each path for this prefix. */
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
@@ -2574,7 +2574,7 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
/* Prefix and num paths displayed once per prefix. */
route_vty_out_detail_header(vty, bgp, dest, (struct prefix *)&p, NULL,
- afi, safi, json);
+ afi, safi, json, false);
evp = (const struct prefix_evpn *)bgp_dest_get_prefix(dest);
@@ -2709,7 +2709,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
/* Prefix and num paths displayed once per prefix. */
route_vty_out_detail_header(vty, bgp, dest, bgp_dest_get_prefix(dest),
- prd, afi, safi, json);
+ prd, afi, safi, json, false);
if (json)
json_paths = json_object_new_array();
@@ -2817,7 +2817,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
/* Prefix and num paths displayed once per prefix. */
route_vty_out_detail_header(
vty, bgp, dest, bgp_dest_get_prefix(dest), prd,
- afi, safi, json_prefix);
+ afi, safi, json_prefix, false);
prefix_cnt++;
}
@@ -2952,7 +2952,7 @@ static void evpn_show_route_rd_all_macip(struct vty *vty, struct bgp *bgp,
/* Prefix and num paths displayed once per prefix. */
route_vty_out_detail_header(
vty, bgp, dest, p, (struct prefix_rd *)rd_destp,
- AFI_L2VPN, SAFI_EVPN, json_prefix);
+ AFI_L2VPN, SAFI_EVPN, json_prefix, false);
/* For EVPN, the prefix is displayed for each path (to
* fit in with code that already exists).
@@ -3106,7 +3106,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
vty, bgp, dest,
bgp_dest_get_prefix(dest),
(struct prefix_rd *)rd_destp, AFI_L2VPN,
- SAFI_EVPN, json_prefix);
+ SAFI_EVPN, json_prefix, false);
/* For EVPN, the prefix is displayed for each path (to
* fit in
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 386c185cdb..0d93abc12f 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -11216,7 +11216,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
- bool json_detail = json_detail_header;
+ bool json_detail_header_used = false;
pi = bgp_dest_get_bgp_path_info(dest);
if (pi == NULL)
@@ -11486,27 +11486,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
: BGP_SHOW_HEADER));
header = false;
- } else if (json_detail && json_paths != NULL) {
- const struct prefix_rd *prd;
- json_object *jtemp;
-
- /* Use common detail header, for most types;
- * need a json 'object'.
- */
-
- jtemp = json_object_new_object();
- prd = bgp_rd_from_dest(dest, safi);
-
- route_vty_out_detail_header(
- vty, bgp, dest,
- bgp_dest_get_prefix(dest), prd,
- table->afi, safi, jtemp);
-
- json_object_array_add(json_paths, jtemp);
-
- json_detail = false;
}
-
if (rd != NULL && !display && !output_count) {
if (!use_json)
vty_out(vty,
@@ -11537,7 +11517,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
bgp_dest_get_prefix(
dest),
prd, table->afi, safi,
- NULL);
+ NULL, false);
route_vty_out_detail(
vty, bgp, dest, dest_p, pi,
@@ -11583,6 +11563,23 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
else
vty_out(vty, ",\"%pFX\": ", dest_p);
}
+
+ if (json_detail_header && json_paths != NULL) {
+ const struct prefix_rd *prd;
+
+ vty_out(vty, "{\n");
+
+ prd = bgp_rd_from_dest(dest, safi);
+
+ route_vty_out_detail_header(
+ vty, bgp, dest,
+ bgp_dest_get_prefix(dest), prd,
+ table->afi, safi, json_paths, true);
+
+ vty_out(vty, "\"paths\": ");
+ json_detail_header_used = true;
+ }
+
/*
* We are using no_pretty here because under
* extremely high settings( say lots and lots of
@@ -11593,6 +11590,10 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
* routers out there
*/
vty_json_no_pretty(vty, json_paths);
+
+ if (json_detail_header_used)
+ vty_out(vty, "} ");
+
json_paths = NULL;
first = 0;
} else
@@ -11777,7 +11778,8 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
struct bgp_dest *dest, const struct prefix *p,
const struct prefix_rd *prd, afi_t afi,
- safi_t safi, json_object *json)
+ safi_t safi, json_object *json,
+ bool incremental_print)
{
struct bgp_path_info *pi;
struct peer *peer;
@@ -11836,16 +11838,27 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
dest->version);
} else {
- json_object_string_addf(json, "prefix", "%pFX", p);
- json_object_int_add(json, "version", dest->version);
-
+ if (incremental_print) {
+ vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
+ vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
+ dest->version);
+ } else {
+ json_object_string_addf(json, "prefix", "%pFX",
+ p);
+ json_object_int_add(json, "version",
+ dest->version);
+ }
}
}
if (has_valid_label) {
- if (json)
- json_object_int_add(json, "localLabel", label);
- else
+ if (json) {
+ if (incremental_print)
+ vty_out(vty, "\"localLabel\": \"%u\",\n",
+ label);
+ else
+ json_object_int_add(json, "localLabel", label);
+ } else
vty_out(vty, "Local label: %d\n", label);
}
@@ -11969,13 +11982,16 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
}
}
- if (json) {
- if (json_adv_to) {
+ if (json && json_adv_to) {
+ if (incremental_print) {
+ vty_out(vty, "\"advertisedTo\": ");
+ vty_json(vty, json_adv_to);
+ vty_out(vty, ",");
+ } else
json_object_object_add(json, "advertisedTo",
json_adv_to);
- }
} else {
- if (first)
+ if (!json && first)
vty_out(vty, " Not advertised to any peer");
vty_out(vty, "\n");
}
@@ -12018,7 +12034,7 @@ static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
route_vty_out_detail_header(
vty, bgp, bgp_node,
bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
- safi, json_header);
+ safi, json_header, false);
header = 0;
}
(*display)++;
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 11ec722f19..d449152c21 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -842,7 +842,8 @@ extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
struct bgp_dest *dest,
const struct prefix *p,
const struct prefix_rd *prd, afi_t afi,
- safi_t safi, json_object *json);
+ safi_t safi, json_object *json,
+ bool incremental_print);
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct bgp_dest *bn, const struct prefix *p,
struct bgp_path_info *path, afi_t afi,
diff --git a/tests/topotests/bgp_aigp/test_bgp_aigp.py b/tests/topotests/bgp_aigp/test_bgp_aigp.py
index b7ea40dd46..6fda459405 100644
--- a/tests/topotests/bgp_aigp/test_bgp_aigp.py
+++ b/tests/topotests/bgp_aigp/test_bgp_aigp.py
@@ -138,30 +138,34 @@ def test_bgp_aigp():
)
expected = {
"routes": {
- "10.0.0.71/32": [
- {
- "aigpMetric": 101,
- "valid": True,
- },
- {
- "aigpMetric": 91,
- "valid": True,
- "bestpath": {"selectionReason": "AIGP"},
- "nexthops": [{"hostname": "r3", "accessible": True}],
- },
- ],
- "10.0.0.72/32": [
- {
- "aigpMetric": 102,
- "valid": True,
- },
- {
- "aigpMetric": 92,
- "valid": True,
- "bestpath": {"selectionReason": "AIGP"},
- "nexthops": [{"hostname": "r3", "accessible": True}],
- },
- ],
+ "10.0.0.71/32": {
+ "paths": [
+ {
+ "aigpMetric": 101,
+ "valid": True,
+ },
+ {
+ "aigpMetric": 91,
+ "valid": True,
+ "bestpath": {"selectionReason": "AIGP"},
+ "nexthops": [{"hostname": "r3", "accessible": True}],
+ },
+ ],
+ },
+ "10.0.0.72/32": {
+ "paths": [
+ {
+ "aigpMetric": 102,
+ "valid": True,
+ },
+ {
+ "aigpMetric": 92,
+ "valid": True,
+ "bestpath": {"selectionReason": "AIGP"},
+ "nexthops": [{"hostname": "r3", "accessible": True}],
+ },
+ ],
+ },
}
}
return topotest.json_cmp(output, expected)
diff --git a/tests/topotests/bgp_community_alias/test_bgp-community-alias.py b/tests/topotests/bgp_community_alias/test_bgp-community-alias.py
index 5b7974c11a..000ea6075b 100644
--- a/tests/topotests/bgp_community_alias/test_bgp-community-alias.py
+++ b/tests/topotests/bgp_community_alias/test_bgp-community-alias.py
@@ -105,12 +105,16 @@ def test_bgp_community_alias():
)
expected = {
"routes": {
- "172.16.16.1/32": [
- {
- "community": {"string": "community-r2-1 65001:2"},
- "largeCommunity": {"string": "large-community-r2-1 65001:1:2"},
- }
- ]
+ "172.16.16.1/32": {
+ "paths": [
+ {
+ "community": {"string": "community-r2-1 65001:2"},
+ "largeCommunity": {
+ "string": "large-community-r2-1 65001:1:2"
+ },
+ }
+ ]
+ }
}
}
return topotest.json_cmp(output, expected)
diff --git a/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py b/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py
index 38fb4c25d0..ebaab60341 100644
--- a/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py
+++ b/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py
@@ -68,24 +68,28 @@ def test_bgp_path_attribute_discard():
output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast json detail"))
expected = {
"routes": {
- "192.168.100.101/32": [
- {
- "valid": True,
- "atomicAggregate": True,
- "community": {
- "string": "65001:101",
- },
- }
- ],
- "192.168.100.102/32": [
- {
- "valid": True,
- "originatorId": "10.0.0.2",
- "community": {
- "string": "65001:102",
- },
- }
- ],
+ "192.168.100.101/32": {
+ "paths": [
+ {
+ "valid": True,
+ "atomicAggregate": True,
+ "community": {
+ "string": "65001:101",
+ },
+ }
+ ],
+ },
+ "192.168.100.102/32": {
+ "paths": [
+ {
+ "valid": True,
+ "originatorId": "10.0.0.2",
+ "community": {
+ "string": "65001:102",
+ },
+ }
+ ],
+ },
}
}
return topotest.json_cmp(output, expected)
@@ -107,20 +111,24 @@ def test_bgp_path_attribute_discard():
output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast json detail"))
expected = {
"routes": {
- "192.168.100.101/32": [
- {
- "valid": True,
- "atomicAggregate": None,
- "community": None,
- }
- ],
- "192.168.100.102/32": [
- {
- "valid": True,
- "originatorId": None,
- "community": None,
- }
- ],
+ "192.168.100.101/32": {
+ "paths": [
+ {
+ "valid": True,
+ "atomicAggregate": None,
+ "community": None,
+ }
+ ],
+ },
+ "192.168.100.102/32": {
+ "paths": [
+ {
+ "valid": True,
+ "originatorId": None,
+ "community": None,
+ }
+ ],
+ },
}
}
return topotest.json_cmp(output, expected)
diff --git a/tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py b/tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py
index 4aa297511a..a9d678a42d 100644
--- a/tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py
+++ b/tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py
@@ -82,17 +82,21 @@ def test_bgp_path_attribute_treat_as_withdraw():
output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast json detail"))
expected = {
"routes": {
- "10.10.10.10/32": [
- {
- "valid": True,
- "atomicAggregate": True,
- }
- ],
- "10.10.10.20/32": [
- {
- "valid": True,
- }
- ],
+ "10.10.10.10/32": {
+ "paths": [
+ {
+ "valid": True,
+ "atomicAggregate": True,
+ }
+ ],
+ },
+ "10.10.10.20/32": {
+ "paths": [
+ {
+ "valid": True,
+ }
+ ],
+ },
}
}
return topotest.json_cmp(output, expected)
@@ -115,11 +119,13 @@ def test_bgp_path_attribute_treat_as_withdraw():
expected = {
"routes": {
"10.10.10.10/32": None,
- "10.10.10.20/32": [
- {
- "valid": True,
- }
- ],
+ "10.10.10.20/32": {
+ "paths": [
+ {
+ "valid": True,
+ }
+ ],
+ },
}
}
return topotest.json_cmp(output, expected)