]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospf6d: Json support added for command "show ipv6 ospf6 spf tree [json]" 8084/head
authorYash Ranjan <ranjany@vmware.com>
Mon, 9 Nov 2020 09:52:45 +0000 (01:52 -0800)
committerYash Ranjan <ranjany@vmware.com>
Tue, 2 Mar 2021 10:14:57 +0000 (02:14 -0800)
Modify code to add JSON format output in show command
"show ipv6 ospf6 spf tree" with proper formating

Signed-off-by: Yash Ranjan <ranjany@vmware.com>
doc/user/ospf6d.rst
ospf6d/ospf6_area.c
ospf6d/ospf6_spf.c
ospf6d/ospf6_spf.h

index 6f8ac978dec24a2830e70a4ff0c1e78412282214..00571487d7825a88d6258e0f4f190d79bbbd547a 100644 (file)
@@ -229,6 +229,15 @@ Showing OSPF6 information
    Interface name can also be given. JSON output can be obtained by appending
    'json' to the end of command.
 
+.. index:: show ipv6 ospf6 spf tree [json]
+.. clicmd:: show ipv6 ospf6 spf tree [json]
+
+   This commands shows the spf tree from the recent spf calculation with the
+   calling router as the root. If json is appended in the end, we can get the
+   tree in JSON format. Each area that the router belongs to has it's own
+   JSON object, with each router having "cost", "isLeafNode" and "children" as
+   arguments.
+   
 OSPF6 Configuration Examples
 ============================
 
index 778bcb9a457763f63ee72c3e78e9ed175d4c36da..898567b4f089ccb903e13d352ed8654c27c53ea0 100644 (file)
@@ -44,6 +44,7 @@
 #include "ospf6_abr.h"
 #include "ospf6_asbr.h"
 #include "ospf6d.h"
+#include "lib/json.h"
 
 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name")
 
@@ -850,12 +851,13 @@ DEFUN (no_area_export_list,
 
 DEFUN (show_ipv6_ospf6_spf_tree,
        show_ipv6_ospf6_spf_tree_cmd,
-       "show ipv6 ospf6 spf tree",
+       "show ipv6 ospf6 spf tree [json]",
        SHOW_STR
        IP6_STR
        OSPF6_STR
        "Shortest Path First calculation\n"
-       "Show SPF tree\n")
+       "Show SPF tree\n"
+        JSON_STR)
 {
        struct listnode *node;
        struct ospf6_area *oa;
@@ -863,20 +865,52 @@ DEFUN (show_ipv6_ospf6_spf_tree,
        struct ospf6_route *route;
        struct prefix prefix;
        struct ospf6 *ospf6;
+       json_object *json = NULL;
+       json_object *json_area = NULL;
+       json_object *json_head = NULL;
+       bool uj = use_json(argc, argv);
 
        ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
        OSPF6_CMD_CHECK_RUNNING(ospf6);
+
+       if (uj)
+               json = json_object_new_object();
        ospf6_linkstate_prefix(ospf6->router_id, htonl(0), &prefix);
 
        for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
+               if (uj) {
+                       json_area = json_object_new_object();
+                       json_head = json_object_new_object();
+               }
                route = ospf6_route_lookup(&prefix, oa->spf_table);
                if (route == NULL) {
-                       vty_out(vty, "LS entry for root not found in area %s\n",
-                               oa->name);
+                       if (uj) {
+                               json_object_string_add(
+                                       json, oa->name,
+                                       "LS entry for not not found");
+                               json_object_free(json_head);
+                               json_object_free(json_area);
+                       } else
+                               vty_out(vty,
+                                       "LS entry for root not found in area %s\n",
+                                       oa->name);
                        continue;
                }
                root = (struct ospf6_vertex *)route->route_option;
-               ospf6_spf_display_subtree(vty, "", 0, root);
+               ospf6_spf_display_subtree(vty, "", 0, root, json_head, uj);
+
+               if (uj) {
+                       json_object_object_add(json_area, root->name,
+                                              json_head);
+                       json_object_object_add(json, oa->name, json_area);
+               }
+       }
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
        }
 
        return CMD_SUCCESS;
@@ -924,7 +958,7 @@ DEFUN (show_ipv6_ospf6_area_spf_tree,
                return CMD_SUCCESS;
        }
        root = (struct ospf6_vertex *)route->route_option;
-       ospf6_spf_display_subtree(vty, "", 0, root);
+       ospf6_spf_display_subtree(vty, "", 0, root, NULL, false);
 
        return CMD_SUCCESS;
 }
@@ -985,7 +1019,7 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
                return CMD_SUCCESS;
        }
        root = (struct ospf6_vertex *)route->route_option;
-       ospf6_spf_display_subtree(vty, "", 0, root);
+       ospf6_spf_display_subtree(vty, "", 0, root, NULL, false);
 
        ospf6_spf_table_finish(spf_table);
        ospf6_route_table_delete(spf_table);
index b3c71462a341ff48c7120807cc0342dbb10ae699..121e846843540ec01eae6d4ddbbc2de8f74e745e 100644 (file)
@@ -722,16 +722,24 @@ void ospf6_spf_schedule(struct ospf6 *ospf6, unsigned int reason)
 }
 
 void ospf6_spf_display_subtree(struct vty *vty, const char *prefix, int rest,
-                              struct ospf6_vertex *v)
+                              struct ospf6_vertex *v, json_object *json_obj,
+                              bool use_json)
 {
        struct listnode *node, *nnode;
        struct ospf6_vertex *c;
        char *next_prefix;
        int len;
        int restnum;
+       json_object *json_childs = NULL;
+       json_object *json_child = NULL;
 
-       /* "prefix" is the space prefix of the display line */
-       vty_out(vty, "%s+-%s [%d]\n", prefix, v->name, v->cost);
+       if (use_json) {
+               json_childs = json_object_new_object();
+               json_object_int_add(json_obj, "cost", v->cost);
+       } else {
+               /* "prefix" is the space prefix of the display line */
+               vty_out(vty, "%s+-%s [%d]\n", prefix, v->name, v->cost);
+       }
 
        len = strlen(prefix) + 4;
        next_prefix = (char *)malloc(len);
@@ -743,10 +751,27 @@ void ospf6_spf_display_subtree(struct vty *vty, const char *prefix, int rest,
 
        restnum = listcount(v->child_list);
        for (ALL_LIST_ELEMENTS(v->child_list, node, nnode, c)) {
-               restnum--;
-               ospf6_spf_display_subtree(vty, next_prefix, restnum, c);
-       }
+               if (use_json)
+                       json_child = json_object_new_object();
+               else
+                       restnum--;
 
+               ospf6_spf_display_subtree(vty, next_prefix, restnum, c,
+                                         json_child, use_json);
+
+               if (use_json)
+                       json_object_object_add(json_childs, c->name,
+                                              json_child);
+       }
+       if (use_json) {
+               json_object_boolean_add(json_obj, "isLeafNode",
+                                       !listcount(v->child_list));
+               if (listcount(v->child_list))
+                       json_object_object_add(json_obj, "children",
+                                              json_childs);
+               else
+                       json_object_free(json_childs);
+       }
        free(next_prefix);
 }
 
index 253888d8ce91219261442749e3908f4491466e0b..36e2b2791225e9672ecc2256231a9e6f34cbda17 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "typesafe.h"
 #include "ospf6_top.h"
+#include "lib/json.h"
 
 /* Debug option */
 extern unsigned char conf_debug_ospf6_spf;
@@ -147,7 +148,8 @@ extern void ospf6_spf_calculation(uint32_t router_id,
 extern void ospf6_spf_schedule(struct ospf6 *ospf, unsigned int reason);
 
 extern void ospf6_spf_display_subtree(struct vty *vty, const char *prefix,
-                                     int rest, struct ospf6_vertex *v);
+                                     int rest, struct ospf6_vertex *v,
+                                     json_object *json_obj, bool use_json);
 
 extern void ospf6_spf_config_write(struct vty *vty, struct ospf6 *ospf6);
 extern int config_write_ospf6_debug_spf(struct vty *vty);