From 31303c3e827f0595a2bf04f3206baf0ecefcedbc Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 5 Oct 2016 20:11:12 +0000 Subject: [PATCH] bgpd: Reduce json memory usage. When running 'show bgp ipv4 uni summ' (or any variation thereof) If you have a large # of routes, the json package starts taking up a tremendous amount of memory and processing power. Modify the code to output the json as we go instead of gathering it all up and outputting at the end. Ticket: CM-13060 Signed-off-by: Donald Sharp Reviewed-by: Don Slice Reviewed-by: Daniel Walton --- bgpd/bgp_route.c | 59 ++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index af0159855d..ec9b127f9d 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7301,9 +7301,8 @@ bgp_show_prefix_longer (struct vty *vty, const char *name, safi_t safi, enum bgp_show_type type); static int -bgp_show_table (struct vty *vty, struct bgp_table *table, - struct in_addr *router_id, enum bgp_show_type type, - void *output_arg, u_char use_json, json_object *json) +bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table, + enum bgp_show_type type, void *output_arg, u_char use_json) { struct bgp_info *ri; struct bgp_node *rn; @@ -7314,16 +7313,15 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, char buf[BUFSIZ]; char buf2[BUFSIZ]; json_object *json_paths = NULL; - json_object *json_routes = NULL; + int first = 1; if (use_json) { - if (json == NULL) - json = json_object_new_object(); - - json_object_int_add(json, "tableVersion", table->version); - json_object_string_add(json, "routerId", inet_ntoa (*router_id)); - json_routes = json_object_new_object(); + vty_out (vty, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 ", \"routerId\": \"%s\", \"routes\": { ", + bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id, + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name, + table->version, inet_ntoa (bgp->router_id)); + json_paths = json_object_new_object(); } /* This is first entry point, so reset total line. */ @@ -7334,7 +7332,10 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, if (rn->info != NULL) { display = 0; - + if (!first && use_json) + { + vty_out (vty, ","); + } if (use_json) json_paths = json_object_new_array(); else @@ -7488,7 +7489,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, if (!use_json && header) { - vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (*router_id), VTY_NEWLINE); + vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE); vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); if (type == bgp_show_type_dampend_paths @@ -7536,16 +7537,19 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, { p = &rn->p; sprintf(buf2, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); - json_object_object_add(json_routes, buf2, json_paths); + vty_out (vty, "\"%s\": ", buf2); + vty_out (vty, "%s", json_object_to_json_string (json_paths)); + json_object_free (json_paths); + first = 0; + } } } if (use_json) { - json_object_object_add(json, "routes", json_routes); - vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); - json_object_free(json); + json_object_free (json_paths); + vty_out (vty, " } }%s", VTY_NEWLINE); } else { @@ -7583,8 +7587,8 @@ bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, table = bgp->rib[afi][safi]; - return bgp_show_table (vty, table, &bgp->router_id, type, output_arg, - use_json, NULL); + return bgp_show_table (vty, bgp, table, type, output_arg, + use_json); } static void @@ -7594,7 +7598,6 @@ bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi, struct listnode *node, *nnode; struct bgp *bgp; struct bgp_table *table; - json_object *json = NULL; int is_first = 1; if (use_json) @@ -7604,20 +7607,6 @@ bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi, { if (use_json) { - if (!(json = json_object_new_object())) - { - zlog_err("Unable to allocate memory for JSON object"); - vty_out (vty, - "{\"error\": {\"message:\": \"Unable to allocate memory for JSON object\"}}}%s", - VTY_NEWLINE); - return; - } - json_object_int_add(json, "vrfId", - (bgp->vrf_id == VRF_UNKNOWN) - ? -1 : bgp->vrf_id); - json_object_string_add(json, "vrfName", - (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) - ? "Default" : bgp->name); if (! is_first) vty_out (vty, ",%s", VTY_NEWLINE); else @@ -7635,8 +7624,8 @@ bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi, VTY_NEWLINE); } table = bgp->rib[afi][safi]; - bgp_show_table (vty, table, &bgp->router_id, - bgp_show_type_normal, NULL, use_json, json); + bgp_show_table (vty, bgp, table, + bgp_show_type_normal, NULL, use_json); } -- 2.39.5