forked from Mirror/frr
bgpd: neighbors received-routes/advertised-routes stringify changes
JSON object could lead to out-of-memory in scaled bgp neighbors received-routes/advertised-routes setup. Changes: not use pretty print and stringify smaller json objects to reduce memory usage free memory after ouput of json object Commands supported with this Json stringify: ``` show bgp vrf <vrf-id> neighbors <nbr-id> advertised-routes json show bgp vrf <vrf-id> neighbors <nbr-id> advertised-routes detail json show bgp vrf <vrf-id> neighbors <nbr-id> advertised-routes <prefix> json show bgp vrf <vrf-id> neighbors <nbr-id> received-routes json show bgp vrf <vrf-id> neighbors <nbr-id> received-routes detail json show bgp vrf <vrf-id> neighbors <nbr-id> received-routes <prefix> json ``` Ticket:#3513253, #3513254 Issue:3513253, 3513254 Signed-off-by: Sindhu Parvathi Gopinathan's <sgopinathan@nvidia.com>
This commit is contained in:
parent
9c5530144a
commit
4838bac033
|
@ -14879,6 +14879,8 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
|
||||||
json_object *json = NULL;
|
json_object *json = NULL;
|
||||||
json_object *json_ar = NULL;
|
json_object *json_ar = NULL;
|
||||||
bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
|
bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
|
||||||
|
bool first = true;
|
||||||
|
struct update_subgroup *subgrp;
|
||||||
|
|
||||||
/* Init BGP headers here so they're only displayed once
|
/* Init BGP headers here so they're only displayed once
|
||||||
* even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
|
* even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
|
||||||
|
@ -14947,6 +14949,28 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
|
||||||
else
|
else
|
||||||
table = bgp->rib[afi][safi];
|
table = bgp->rib[afi][safi];
|
||||||
|
|
||||||
|
subgrp = peer_subgroup(peer, afi, safi);
|
||||||
|
if (use_json) {
|
||||||
|
if (type == bgp_show_adj_route_advertised || type == bgp_show_adj_route_received) {
|
||||||
|
if (header1) {
|
||||||
|
int version = table ? table->version : 0;
|
||||||
|
vty_out(vty, "\"bgpTableVersion\":%d", version);
|
||||||
|
vty_out(vty, ",\"bgpLocalRouterId\":\"%pI4\"", &bgp->router_id);
|
||||||
|
vty_out(vty, ",\"defaultLocPrf\":%u", bgp->default_local_pref);
|
||||||
|
vty_out(vty, ",\"localAS\":%u", bgp->as);
|
||||||
|
if (type == bgp_show_adj_route_advertised && subgrp &&
|
||||||
|
CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
|
||||||
|
vty_out(vty, ",\"bgpOriginatingDefaultNetwork\":\"%s\"",
|
||||||
|
(afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == bgp_show_adj_route_advertised)
|
||||||
|
vty_out(vty, ",\"advertisedRoutes\": ");
|
||||||
|
if (type == bgp_show_adj_route_received)
|
||||||
|
vty_out(vty, ",\"receivedRoutes\": ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
|
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
|
||||||
|| (safi == SAFI_EVPN)) {
|
|| (safi == SAFI_EVPN)) {
|
||||||
|
|
||||||
|
@ -14965,6 +14989,7 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
|
||||||
json_routes = json_object_new_object();
|
json_routes = json_object_new_object();
|
||||||
|
|
||||||
const struct prefix_rd *prd;
|
const struct prefix_rd *prd;
|
||||||
|
|
||||||
prd = (const struct prefix_rd *)bgp_dest_get_prefix(
|
prd = (const struct prefix_rd *)bgp_dest_get_prefix(
|
||||||
dest);
|
dest);
|
||||||
|
|
||||||
|
@ -14978,32 +15003,54 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
|
||||||
&filtered_count_per_rd);
|
&filtered_count_per_rd);
|
||||||
|
|
||||||
/* Don't include an empty RD in the output! */
|
/* Don't include an empty RD in the output! */
|
||||||
if (json_routes && (output_count_per_rd > 0))
|
if (json_routes && (output_count_per_rd > 0) && use_json) {
|
||||||
json_object_object_add(json_ar, rd_str,
|
if (type == bgp_show_adj_route_advertised ||
|
||||||
json_routes);
|
type == bgp_show_adj_route_received) {
|
||||||
|
if (first) {
|
||||||
|
vty_out(vty, "\"%s\":", rd_str);
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
vty_out(vty, ",\"%s\":", rd_str);
|
||||||
|
}
|
||||||
|
vty_json_no_pretty(vty, json_routes);
|
||||||
|
} else {
|
||||||
|
json_object_object_add(json_ar, rd_str, json_routes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
output_count += output_count_per_rd;
|
output_count += output_count_per_rd;
|
||||||
filtered_count += filtered_count_per_rd;
|
filtered_count += filtered_count_per_rd;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
|
show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
|
||||||
json, json_ar, show_flags, &header1, &header2,
|
json, json_ar, show_flags, &header1, &header2,
|
||||||
rd_str, match, &output_count, &filtered_count);
|
rd_str, match, &output_count, &filtered_count);
|
||||||
|
|
||||||
if (use_json) {
|
if (use_json) {
|
||||||
if (type == bgp_show_adj_route_advertised)
|
if (type == bgp_show_adj_route_advertised ||
|
||||||
json_object_object_add(json, "advertisedRoutes",
|
type == bgp_show_adj_route_received) {
|
||||||
json_ar);
|
vty_json_no_pretty(vty, json_ar);
|
||||||
else
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_json) {
|
||||||
|
if (type == bgp_show_adj_route_advertised || type == bgp_show_adj_route_received) {
|
||||||
|
vty_out(vty, ",\"totalPrefixCounter\":%lu", output_count);
|
||||||
|
vty_out(vty, ",\"filteredPrefixCounter\":%lu", filtered_count);
|
||||||
|
json_object_free(json);
|
||||||
|
} else {
|
||||||
|
/* for bgp_show_adj_route_filtered & bgp_show_adj_route_bestpath type */
|
||||||
json_object_object_add(json, "receivedRoutes", json_ar);
|
json_object_object_add(json, "receivedRoutes", json_ar);
|
||||||
json_object_int_add(json, "totalPrefixCounter", output_count);
|
json_object_int_add(json, "totalPrefixCounter", output_count);
|
||||||
json_object_int_add(json, "filteredPrefixCounter",
|
json_object_int_add(json, "filteredPrefixCounter", filtered_count);
|
||||||
filtered_count);
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an extremely expensive operation at scale
|
* This is an extremely expensive operation at scale
|
||||||
* and non-pretty reduces memory footprint significantly.
|
* and non-pretty reduces memory footprint significantly.
|
||||||
*/
|
*/
|
||||||
|
if ((type != bgp_show_adj_route_advertised) && (type != bgp_show_adj_route_received))
|
||||||
vty_json_no_pretty(vty, json);
|
vty_json_no_pretty(vty, json);
|
||||||
} else if (output_count > 0) {
|
} else if (output_count > 0) {
|
||||||
if (!match && filtered_count > 0)
|
if (!match && filtered_count > 0)
|
||||||
|
@ -15108,6 +15155,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
|
||||||
uint16_t show_flags = 0;
|
uint16_t show_flags = 0;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct bgp *abgp;
|
struct bgp *abgp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (detail || prefix_str)
|
if (detail || prefix_str)
|
||||||
SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
|
SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
|
||||||
|
@ -15149,9 +15197,22 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
|
||||||
else if (argv_find(argv, argc, "filtered-routes", &idx))
|
else if (argv_find(argv, argc, "filtered-routes", &idx))
|
||||||
type = bgp_show_adj_route_filtered;
|
type = bgp_show_adj_route_filtered;
|
||||||
|
|
||||||
if (!all)
|
if (!all) {
|
||||||
return peer_adj_routes(vty, peer, afi, safi, type, route_map,
|
if (uj)
|
||||||
|
if (type == bgp_show_adj_route_advertised ||
|
||||||
|
type == bgp_show_adj_route_received)
|
||||||
|
vty_out(vty, "{\n");
|
||||||
|
|
||||||
|
ret = peer_adj_routes(vty, peer, afi, safi, type, route_map,
|
||||||
prefix_str ? prefix : NULL, show_flags);
|
prefix_str ? prefix : NULL, show_flags);
|
||||||
|
if (uj)
|
||||||
|
if (type == bgp_show_adj_route_advertised ||
|
||||||
|
type == bgp_show_adj_route_received)
|
||||||
|
vty_out(vty, "}\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (uj)
|
if (uj)
|
||||||
vty_out(vty, "{\n");
|
vty_out(vty, "{\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue