isisd: Add json to show isis database command.

Signed-off-by: Javier Garcia <javier.martin.garcia@ibm.com>
This commit is contained in:
Javier Garcia 2022-02-24 11:31:18 +01:00
parent a21177f280
commit a2cac12a63
8 changed files with 1161 additions and 357 deletions

View file

@ -290,7 +290,7 @@ Showing ISIS information
Show state and information of ISIS specified neighbor, or all neighbors if
no system id is given with or without details.
.. clicmd:: show isis database [detail] [LSPID]
.. clicmd:: show isis [vrf <NAME|all>] database [detail] [LSPID] [json]
Show the ISIS database globally, for a specific LSP id without or with
details.

View file

@ -733,8 +733,48 @@ static const char *lsp_bits2string(uint8_t lsp_bits, char *buf, size_t buf_size)
}
/* this function prints the lsp on show isis database */
void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost,
struct isis *isis)
void lsp_print_common(struct isis_lsp *lsp, struct vty *vty, struct json_object *json,
char dynhost, struct isis *isis)
{
if (json) {
return lsp_print_json(lsp, json, dynhost, isis);
} else {
return lsp_print_vty(lsp, vty, dynhost, isis);
}
}
void lsp_print_json(struct isis_lsp *lsp, struct json_object *json,
char dynhost, struct isis *isis)
{
char LSPid[255];
char age_out[8];
char b[200];
json_object *own_json;
char buf[256];
lspid_print(lsp->hdr.lsp_id, LSPid, sizeof(LSPid), dynhost, 1, isis);
own_json = json_object_new_object();
json_object_object_add(json, "lsp", own_json);
json_object_string_add(own_json, "id", LSPid);
json_object_string_add(own_json, "own", lsp->own_lsp ? "*" : " ");
json_object_int_add(json, "pdu-len", lsp->hdr.pdu_len);
snprintfrr(buf, sizeof(buf), "0x%08x", lsp->hdr.seqno);
json_object_string_add(json, "seq-number", buf);
snprintfrr(buf, sizeof(buf), "0x%04hx", lsp->hdr.checksum);
json_object_string_add(json, "chksum", buf);
if (lsp->hdr.rem_lifetime == 0) {
snprintf(age_out, sizeof(age_out), "(%d)", lsp->age_out);
age_out[7] = '\0';
json_object_string_add(json, "holdtime", age_out);
} else {
json_object_int_add(json, "holdtime", lsp->hdr.rem_lifetime);
}
json_object_string_add(
json, "att-p-ol", lsp_bits2string(lsp->hdr.lsp_bits, b, sizeof(b)));
}
void lsp_print_vty(struct isis_lsp *lsp, struct vty *vty,
char dynhost, struct isis *isis)
{
char LSPid[255];
char age_out[8];
@ -754,30 +794,40 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost,
vty_out(vty, "%s\n", lsp_bits2string(lsp->hdr.lsp_bits, b, sizeof(b)));
}
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost,
struct isis *isis)
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty,
struct json_object *json, char dynhost,
struct isis *isis)
{
lsp_print(lsp, vty, dynhost, isis);
if (lsp->tlvs)
vty_multiline(vty, " ", "%s", isis_format_tlvs(lsp->tlvs));
vty_out(vty, "\n");
if (json) {
lsp_print_json(lsp, json, dynhost, isis);
if (lsp->tlvs) {
isis_format_tlvs(lsp->tlvs, json);
}
} else {
lsp_print_vty(lsp, vty, dynhost, isis);
if (lsp->tlvs)
vty_multiline(vty, " ", "%s",
isis_format_tlvs(lsp->tlvs, NULL));
vty_out(vty, "\n");
}
}
/* print all the lsps info in the local lspdb */
int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail,
char dynhost, struct isis *isis)
int lsp_print_all(struct vty *vty, struct json_object *json,
struct lspdb_head *head, char detail, char dynhost,
struct isis *isis)
{
struct isis_lsp *lsp;
int lsp_count = 0;
if (detail == ISIS_UI_LEVEL_BRIEF) {
frr_each (lspdb, head, lsp) {
lsp_print(lsp, vty, dynhost, isis);
lsp_print_common(lsp, vty, json, dynhost, isis);
lsp_count++;
}
} else if (detail == ISIS_UI_LEVEL_DETAIL) {
frr_each (lspdb, head, lsp) {
lsp_print_detail(lsp, vty, dynhost, isis);
lsp_print_detail(lsp, vty, json, dynhost, isis);
lsp_count++;
}
}
@ -1264,7 +1314,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
if (!fragments) {
zlog_warn("BUG: could not fragment own LSP:");
log_multiline(LOG_WARNING, " ", "%s",
isis_format_tlvs(tlvs));
isis_format_tlvs(tlvs, NULL));
isis_free_tlvs(tlvs);
return;
}

View file

@ -120,12 +120,19 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno);
void lspid_print(uint8_t *lsp_id, char *dest, size_t dest_len, char dynhost,
char frag, struct isis *isis);
void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost,
struct isis *isis);
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost,
void lsp_print_common(struct isis_lsp *lsp, struct vty *vty,
struct json_object *json, char dynhost,
struct isis *isis);
int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail,
char dynhost, struct isis *isis);
void lsp_print_vty(struct isis_lsp *lsp, struct vty *vty, char dynhost,
struct isis *isis);
void lsp_print_json(struct isis_lsp *lsp, struct json_object *json,
char dynhost, struct isis *isis);
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty,
struct json_object *json, char dynhost,
struct isis *isis);
int lsp_print_all(struct vty *vty, struct json_object *json,
struct lspdb_head *head, char detail, char dynhost,
struct isis *isis);
/* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set);

View file

@ -2209,7 +2209,7 @@ int send_csnp(struct isis_circuit *circuit, int level)
circuit->interface->name,
stream_get_endp(circuit->snd_stream));
log_multiline(LOG_DEBUG, " ", "%s",
isis_format_tlvs(tlvs));
isis_format_tlvs(tlvs, NULL));
if (IS_DEBUG_PACKET_DUMP)
zlog_dump_data(
STREAM_DATA(circuit->snd_stream),
@ -2372,7 +2372,7 @@ static int send_psnp(int level, struct isis_circuit *circuit)
circuit->interface->name,
stream_get_endp(circuit->snd_stream));
log_multiline(LOG_DEBUG, " ", "%s",
isis_format_tlvs(tlvs));
isis_format_tlvs(tlvs, NULL));
if (IS_DEBUG_PACKET_DUMP)
zlog_dump_data(
STREAM_DATA(circuit->snd_stream),

File diff suppressed because it is too large Load diff

View file

@ -549,7 +549,7 @@ void isis_free_tlvs(struct isis_tlvs *tlvs);
struct isis_tlvs *isis_alloc_tlvs(void);
int isis_unpack_tlvs(size_t avail_len, struct stream *stream,
struct isis_tlvs **dest, const char **error_log);
const char *isis_format_tlvs(struct isis_tlvs *tlvs);
const char *isis_format_tlvs(struct isis_tlvs *tlvs, struct json_object *json);
struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs);
struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size);

View file

@ -209,7 +209,7 @@ struct isis *isis_new(const char *vrf_name)
/*
* Default values
*/
isis->max_area_addrs = 3;
isis->max_area_addrs = ISIS_DEFAULT_MAX_AREA_ADDRESSES;
isis->process_id = getpid();
isis->router_id = 0;
isis->area_list = list_new();
@ -2654,9 +2654,40 @@ struct isis_lsp *lsp_for_sysid(struct lspdb_head *head, const char *sysid_str,
return lsp;
}
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
int level, struct lspdb_head *lspdb,
const char *sysid_str, int ui_level)
void show_isis_database_lspdb_json(struct json_object *json,
struct isis_area *area, int level,
struct lspdb_head *lspdb,
const char *sysid_str, int ui_level)
{
struct isis_lsp *lsp;
int lsp_count;
if (lspdb_count(lspdb) > 0) {
lsp = lsp_for_sysid(lspdb, sysid_str, area->isis);
if (lsp != NULL || sysid_str == NULL) {
json_object_int_add(json, "id", level + 1);
}
if (lsp) {
if (ui_level == ISIS_UI_LEVEL_DETAIL)
lsp_print_detail(lsp, NULL, json,
area->dynhostname, area->isis);
else
lsp_print_json(lsp, json, area->dynhostname,
area->isis);
} else if (sysid_str == NULL) {
lsp_count =
lsp_print_all(NULL, json, lspdb, ui_level,
area->dynhostname, area->isis);
json_object_int_add(json, "count", lsp_count);
}
}
}
void show_isis_database_lspdb_vty(struct vty *vty, struct isis_area *area,
int level, struct lspdb_head *lspdb,
const char *sysid_str, int ui_level)
{
struct isis_lsp *lsp;
int lsp_count;
@ -2675,14 +2706,14 @@ void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
if (lsp) {
if (ui_level == ISIS_UI_LEVEL_DETAIL)
lsp_print_detail(lsp, vty, area->dynhostname,
area->isis);
lsp_print_detail(lsp, vty, NULL,
area->dynhostname, area->isis);
else
lsp_print(lsp, vty, area->dynhostname,
area->isis);
lsp_print_vty(lsp, vty, area->dynhostname,
area->isis);
} else if (sysid_str == NULL) {
lsp_count =
lsp_print_all(vty, lspdb, ui_level,
lsp_print_all(vty, NULL, lspdb, ui_level,
area->dynhostname, area->isis);
vty_out(vty, " %u LSPs\n\n", lsp_count);
@ -2690,7 +2721,43 @@ void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
}
}
static void show_isis_database_common(struct vty *vty, const char *sysid_str,
static void show_isis_database_json(struct json_object *json, const char *sysid_str,
int ui_level, struct isis *isis)
{
struct listnode *node;
struct isis_area *area;
int level;
struct json_object *tag_area_json,*area_json, *lsp_json, *area_arr_json, *arr_json;
uint8_t area_cnt = 0;
if (isis->area_list->count == 0)
return;
area_arr_json = json_object_new_array();
json_object_object_add(json, "areas", area_arr_json);
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
area_json = json_object_new_object();
tag_area_json = json_object_new_object();
json_object_string_add(tag_area_json, "name",
area->area_tag ? area->area_tag
: "null");
arr_json = json_object_new_array();
json_object_object_add(area_json,"area",tag_area_json);
json_object_object_add(area_json,"levels",arr_json);
for (level = 0; level < ISIS_LEVELS; level++) {
lsp_json = json_object_new_object();
show_isis_database_lspdb_json(lsp_json, area, level,
&area->lspdb[level],
sysid_str, ui_level);
json_object_array_add(arr_json, lsp_json);
}
json_object_array_add(area_arr_json, area_json);
area_cnt++;
}
}
static void show_isis_database_vty(struct vty *vty, const char *sysid_str,
int ui_level, struct isis *isis)
{
struct listnode *node;
@ -2705,11 +2772,22 @@ static void show_isis_database_common(struct vty *vty, const char *sysid_str,
area->area_tag ? area->area_tag : "null");
for (level = 0; level < ISIS_LEVELS; level++)
show_isis_database_lspdb(vty, area, level,
show_isis_database_lspdb_vty(vty, area, level,
&area->lspdb[level], sysid_str,
ui_level);
}
}
static void show_isis_database_common(struct vty *vty, struct json_object *json, const char *sysid_str,
int ui_level, struct isis *isis)
{
if (json) {
show_isis_database_json(json, sysid_str, ui_level, isis);
} else {
show_isis_database_vty(vty, sysid_str, ui_level, isis);
}
}
/*
* This function supports following display options:
* [ show isis database [detail] ]
@ -2726,7 +2804,7 @@ static void show_isis_database_common(struct vty *vty, const char *sysid_str,
* [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
* [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
*/
static int show_isis_database(struct vty *vty, const char *sysid_str,
static int show_isis_database(struct vty *vty, struct json_object *json, const char *sysid_str,
int ui_level, const char *vrf_name, bool all_vrf)
{
struct listnode *node;
@ -2735,28 +2813,30 @@ static int show_isis_database(struct vty *vty, const char *sysid_str,
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
show_isis_database_common(vty, sysid_str,
show_isis_database_common(vty, json, sysid_str,
ui_level, isis);
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis)
show_isis_database_common(vty, sysid_str, ui_level,
isis);
show_isis_database_common(vty, json, sysid_str,
ui_level, isis);
}
return CMD_SUCCESS;
}
DEFUN(show_database, show_database_cmd,
"show " PROTO_NAME " [vrf <NAME|all>] database [detail] [WORD]",
"show " PROTO_NAME " [vrf <NAME|all>] database [detail] [WORD] [json]",
SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
"All VRFs\n"
"Link state database\n"
"Detailed information\n"
"LSP ID\n")
"LSP ID\n"
"json output\n")
{
int res = CMD_SUCCESS;
int idx = 0;
int idx_vrf = 0;
const char *vrf_name = VRF_DEFAULT_NAME;
@ -2765,8 +2845,17 @@ DEFUN(show_database, show_database_cmd,
? ISIS_UI_LEVEL_DETAIL
: ISIS_UI_LEVEL_BRIEF;
char *id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
bool uj = use_json(argc, argv);
json_object *json = NULL;
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
return show_isis_database(vty, id, uilevel, vrf_name, all_vrf);
if (uj)
json = json_object_new_object();
res = show_isis_database(vty, json, id, uilevel, vrf_name, all_vrf);
if (uj)
vty_json(vty, json);
return res;
}
#ifdef FABRICD

View file

@ -89,6 +89,8 @@ struct isis_master {
};
#define F_ISIS_UNIT_TEST 0x01
#define ISIS_DEFAULT_MAX_AREA_ADDRESSES 3
struct isis {
vrf_id_t vrf_id;
char *name;
@ -305,9 +307,13 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
const char *passwd, uint8_t snp_auth);
int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
const char *passwd, uint8_t snp_auth);
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
int level, struct lspdb_head *lspdb,
const char *argv, int ui_level);
void show_isis_database_lspdb_json(struct json_object *json,
struct isis_area *area, int level,
struct lspdb_head *lspdb, const char *argv,
int ui_level);
void show_isis_database_lspdb_vty(struct vty *vty, struct isis_area *area,
int level, struct lspdb_head *lspdb,
const char *argv, int ui_level);
/* YANG paths */
#define ISIS_INSTANCE "/frr-isisd:isis/instance"