]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: show bgp l2vpn evpn route detail json stringify changes
authorAshwini Reddy <ashred@nvidia.com>
Thu, 2 Nov 2023 01:46:08 +0000 (18:46 -0700)
committerKrishnasamy R <krishnasamyr@nvidia.com>
Sat, 16 Nov 2024 06:49:01 +0000 (22:49 -0800)
Json object could lead to out-of-memory in scaled bgp l2vpn evpn route setup.

Changes:

- not use pretty print and stringify smaller json objects to reduce memory
usage
- free memory after ouput of json_rd
- minor formatting of json output

Commands supported with this Json stringify:

show bgp l2vpn evpn route detail json
show bgp l2vpn evpn route detail type 2 json
show bgp l2vpn evpn route detail type 2 self-originate json
show bgp l2vpn evpn route detail self-originate json
show bgp l2vpn evpn route json
show bgp l2vpn evpn route type 2 json
show bgp l2vpn evpn route type 2 self-originate json
show bgp l2vpn evpn route self-originate json

Ticket:#3513249

Issue:3513249

Signed-off-by: Ashwini Reddy <ashred@nvidia.com>
Signed-off-by: Sindhu Parvathi Gopinathan's <sgopinathan@nvidia.com>
bgpd/bgp_evpn_vty.c

index 958a9c6492b58fb2157228562dfbe2bf455ff140..16b149e5b567bcdaeee36b85707ce9a8f7c830f4 100644 (file)
@@ -3115,6 +3115,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
        afi_t afi;
        safi_t safi;
        uint32_t prefix_cnt, path_cnt;
+       int first = true;
 
        afi = AFI_L2VPN;
        safi = SAFI_EVPN;
@@ -3139,8 +3140,15 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
                prefix_rd2str((struct prefix_rd *)rd_destp, rd_str,
                              sizeof(rd_str), bgp->asnotation);
 
-               if (json)
+               if (json) {
+                       if (first) {
+                               vty_out(vty, "\"%s\":", rd_str);
+                               first = false;
+                       } else {
+                               vty_out(vty, ",\"%s\":", rd_str);
+                       }
                        json_rd = json_object_new_object();
+               }
 
                rd_header = 1;
 
@@ -3255,18 +3263,18 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
                }
 
                if (json) {
-                       if (add_rd_to_json)
-                               json_object_object_add(json, rd_str, json_rd);
-                       else {
+                       if (add_rd_to_json) {
+                               vty_json_no_pretty(vty, json_rd);
+                       } else {
+                               vty_out(vty, "{}");
                                json_object_free(json_rd);
-                               json_rd = NULL;
                        }
                }
        }
 
        if (json) {
-               json_object_int_add(json, "numPrefix", prefix_cnt);
-               json_object_int_add(json, "numPaths", path_cnt);
+               vty_out(vty, ",\"numPrefix\":%u", prefix_cnt);
+               vty_out(vty, ",\"numPaths\":%u", path_cnt);
        } else {
                if (prefix_cnt == 0) {
                        vty_out(vty, "No EVPN prefixes %sexist\n",
@@ -3284,20 +3292,18 @@ int bgp_evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
 {
        json_object *json = NULL;
 
-       if (use_json)
+       if (use_json) {
                json = json_object_new_object();
+               vty_out(vty, "{\n");
+       }
 
        evpn_show_all_routes(vty, bgp, type, json, detail, false);
 
-       if (use_json)
-               /*
-                * We are using no_pretty here because under extremely high
-                * settings (lots of routes with many different paths) this can
-                * save several minutes of output when FRR is run on older cpu's
-                * or more underperforming routers out there. So for route
-                * scale, we need to use no_pretty json.
-                */
-               vty_json_no_pretty(vty, json);
+       if (use_json) {
+               vty_out(vty, "}\n");
+               json_object_free(json);
+       }
+
        return CMD_SUCCESS;
 }
 
@@ -4946,8 +4952,10 @@ DEFUN(show_bgp_l2vpn_evpn_route,
        if (!bgp)
                return CMD_WARNING;
 
-       if (uj)
+       if (uj) {
                json = json_object_new_object();
+               vty_out(vty, "{\n");
+       }
 
        if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
                return CMD_WARNING;
@@ -4960,13 +4968,10 @@ DEFUN(show_bgp_l2vpn_evpn_route,
 
        evpn_show_all_routes(vty, bgp, type, json, detail, self_orig);
 
-       /*
-        * This is an extremely expensive operation at scale
-        * and as such we need to save as much time as is
-        * possible.
-        */
-       if (uj)
-               vty_json_no_pretty(vty, json);
+       if (uj) {
+               vty_out(vty, "}\n");
+               json_object_free(json);
+       }
 
        return CMD_SUCCESS;
 }
@@ -5023,10 +5028,20 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
        if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
                return CMD_WARNING;
 
-       if (rd_all)
+       if (rd_all) {
+               if (uj)
+                       vty_out(vty, "{\n");
+
                evpn_show_all_routes(vty, bgp, type, json, 1, false);
-       else
+
+               if (uj) {
+                       vty_out(vty, "}\n");
+                       json_object_free(json);
+                       return CMD_SUCCESS;
+               }
+       } else {
                evpn_show_route_rd(vty, bgp, &prd, type, json);
+       }
 
        if (uj)
                vty_json(vty, json);