]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Fix memory leak in json output of show commands
authorDonald Sharp <sharpd@cumulusnetworks.com>
Sun, 1 Dec 2019 14:29:32 +0000 (09:29 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 2 Dec 2019 00:37:38 +0000 (19:37 -0500)
When dumping a large bit of table data via bgp_show_table
and if there is no information to display for a particular
`struct bgp_node *` the data allocated via json_object_new_array()
is leaked.  Not a big deal on small tables but if you have a full
bgp feed and issue a show command that does not match any of
the route nodes ( say `vtysh -c "show bgp ipv4 large-community-list FOO"`)
then we will leak memory.

Before code change and issuing the above show bgp large-community-list command 15-20 times:
Memory statistics for bgpd:
System allocator statistics:
  Total heap allocated:  > 2GB
  Holding block headers: 0 bytes
  Used small blocks:     0 bytes
  Used ordinary blocks:  > 2GB
  Free small blocks:     31 MiB
  Free ordinary blocks:  616 KiB
  Ordinary blocks:       0
  Small blocks:          0
  Holding blocks:        0

After:

Memory statistics for bgpd:
System allocator statistics:
  Total heap allocated:  924 MiB
  Holding block headers: 0 bytes
  Used small blocks:     0 bytes
  Used ordinary blocks:  558 MiB
  Free small blocks:     26 MiB
  Free ordinary blocks:  340 MiB
  Ordinary blocks:       0
  Small blocks:          0
  Holding blocks:        0

Please note the 340mb of free ordinary blocks is from the fact I issued a
`show bgp ipv4 uni json` command and generated a large amount of data.

Fixes: #5445
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd/bgp_route.c

index 082c61df38a93b183a0d4848fc80ece281cc38ad..3e1d6f67d1e4b6f1b8f9633017a8632a62c41d20 100644 (file)
@@ -9073,7 +9073,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                        json_object_free(json_paths);
                        json_paths = NULL;
                        first = 0;
-               }
+               } else
+                       json_object_free(json_paths);
        }
 
        if (output_cum) {