ospf6d: Json support added for command "show ipv6 ospf6 spf tree [json]"

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>
This commit is contained in:
Yash Ranjan 2020-11-09 01:52:45 -08:00
parent c103ac43de
commit 305b639bca
4 changed files with 84 additions and 14 deletions

View 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
============================

View 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);

View 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);
}

View 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);