]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Reduce json memory usage.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 5 Oct 2016 20:11:12 +0000 (20:11 +0000)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 10 Oct 2016 14:51:54 +0000 (10:51 -0400)
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 <sharpd@cumulusnetworks.com>
Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
bgpd/bgp_route.c

index af0159855d3afd96f3a8f2bcb5f3ddf5ce817ce8..ec9b127f9dcfd6c3f3dea733a06bf63ced88ae37 100644 (file)
@@ -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);
 
     }