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 Show state and information of ISIS specified neighbor, or all neighbors if
no system id is given with or without details. 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 Show the ISIS database globally, for a specific LSP id without or with
details. 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 */ /* this function prints the lsp on show isis database */
void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost, void lsp_print_common(struct isis_lsp *lsp, struct vty *vty, struct json_object *json,
struct isis *isis) 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 LSPid[255];
char age_out[8]; 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))); 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, void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty,
struct json_object *json, char dynhost,
struct isis *isis) struct isis *isis)
{ {
lsp_print(lsp, vty, dynhost, isis); 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) if (lsp->tlvs)
vty_multiline(vty, " ", "%s", isis_format_tlvs(lsp->tlvs)); vty_multiline(vty, " ", "%s",
isis_format_tlvs(lsp->tlvs, NULL));
vty_out(vty, "\n"); vty_out(vty, "\n");
}
} }
/* print all the lsps info in the local lspdb */ /* print all the lsps info in the local lspdb */
int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail, int lsp_print_all(struct vty *vty, struct json_object *json,
char dynhost, struct isis *isis) struct lspdb_head *head, char detail, char dynhost,
struct isis *isis)
{ {
struct isis_lsp *lsp; struct isis_lsp *lsp;
int lsp_count = 0; int lsp_count = 0;
if (detail == ISIS_UI_LEVEL_BRIEF) { if (detail == ISIS_UI_LEVEL_BRIEF) {
frr_each (lspdb, head, lsp) { frr_each (lspdb, head, lsp) {
lsp_print(lsp, vty, dynhost, isis); lsp_print_common(lsp, vty, json, dynhost, isis);
lsp_count++; lsp_count++;
} }
} else if (detail == ISIS_UI_LEVEL_DETAIL) { } else if (detail == ISIS_UI_LEVEL_DETAIL) {
frr_each (lspdb, head, lsp) { frr_each (lspdb, head, lsp) {
lsp_print_detail(lsp, vty, dynhost, isis); lsp_print_detail(lsp, vty, json, dynhost, isis);
lsp_count++; lsp_count++;
} }
} }
@ -1264,7 +1314,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
if (!fragments) { if (!fragments) {
zlog_warn("BUG: could not fragment own LSP:"); zlog_warn("BUG: could not fragment own LSP:");
log_multiline(LOG_WARNING, " ", "%s", log_multiline(LOG_WARNING, " ", "%s",
isis_format_tlvs(tlvs)); isis_format_tlvs(tlvs, NULL));
isis_free_tlvs(tlvs); isis_free_tlvs(tlvs);
return; 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 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, void lspid_print(uint8_t *lsp_id, char *dest, size_t dest_len, char dynhost,
char frag, struct isis *isis); char frag, struct isis *isis);
void lsp_print(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); struct isis *isis);
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost, void lsp_print_vty(struct isis_lsp *lsp, struct vty *vty, char dynhost,
struct isis *isis); struct isis *isis);
int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail, void lsp_print_json(struct isis_lsp *lsp, struct json_object *json,
char dynhost, struct isis *isis); 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 */ /* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set); 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, circuit->interface->name,
stream_get_endp(circuit->snd_stream)); stream_get_endp(circuit->snd_stream));
log_multiline(LOG_DEBUG, " ", "%s", log_multiline(LOG_DEBUG, " ", "%s",
isis_format_tlvs(tlvs)); isis_format_tlvs(tlvs, NULL));
if (IS_DEBUG_PACKET_DUMP) if (IS_DEBUG_PACKET_DUMP)
zlog_dump_data( zlog_dump_data(
STREAM_DATA(circuit->snd_stream), STREAM_DATA(circuit->snd_stream),
@ -2372,7 +2372,7 @@ static int send_psnp(int level, struct isis_circuit *circuit)
circuit->interface->name, circuit->interface->name,
stream_get_endp(circuit->snd_stream)); stream_get_endp(circuit->snd_stream));
log_multiline(LOG_DEBUG, " ", "%s", log_multiline(LOG_DEBUG, " ", "%s",
isis_format_tlvs(tlvs)); isis_format_tlvs(tlvs, NULL));
if (IS_DEBUG_PACKET_DUMP) if (IS_DEBUG_PACKET_DUMP)
zlog_dump_data( zlog_dump_data(
STREAM_DATA(circuit->snd_stream), 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); struct isis_tlvs *isis_alloc_tlvs(void);
int isis_unpack_tlvs(size_t avail_len, struct stream *stream, int isis_unpack_tlvs(size_t avail_len, struct stream *stream,
struct isis_tlvs **dest, const char **error_log); 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 isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs);
struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size); 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 * Default values
*/ */
isis->max_area_addrs = 3; isis->max_area_addrs = ISIS_DEFAULT_MAX_AREA_ADDRESSES;
isis->process_id = getpid(); isis->process_id = getpid();
isis->router_id = 0; isis->router_id = 0;
isis->area_list = list_new(); isis->area_list = list_new();
@ -2654,7 +2654,38 @@ struct isis_lsp *lsp_for_sysid(struct lspdb_head *head, const char *sysid_str,
return lsp; return lsp;
} }
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area, 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, int level, struct lspdb_head *lspdb,
const char *sysid_str, int ui_level) const char *sysid_str, int ui_level)
{ {
@ -2675,14 +2706,14 @@ void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
if (lsp) { if (lsp) {
if (ui_level == ISIS_UI_LEVEL_DETAIL) if (ui_level == ISIS_UI_LEVEL_DETAIL)
lsp_print_detail(lsp, vty, area->dynhostname, lsp_print_detail(lsp, vty, NULL,
area->isis); area->dynhostname, area->isis);
else else
lsp_print(lsp, vty, area->dynhostname, lsp_print_vty(lsp, vty, area->dynhostname,
area->isis); area->isis);
} else if (sysid_str == NULL) { } else if (sysid_str == NULL) {
lsp_count = lsp_count =
lsp_print_all(vty, lspdb, ui_level, lsp_print_all(vty, NULL, lspdb, ui_level,
area->dynhostname, area->isis); area->dynhostname, area->isis);
vty_out(vty, " %u LSPs\n\n", lsp_count); 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) int ui_level, struct isis *isis)
{ {
struct listnode *node; 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"); area->area_tag ? area->area_tag : "null");
for (level = 0; level < ISIS_LEVELS; level++) 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, &area->lspdb[level], sysid_str,
ui_level); 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: * This function supports following display options:
* [ show isis database [detail] ] * [ 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 <sysid>.<pseudo-id>-<fragment-number> ]
* [ show isis database detail <hostname>.<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) int ui_level, const char *vrf_name, bool all_vrf)
{ {
struct listnode *node; struct listnode *node;
@ -2735,28 +2813,30 @@ static int show_isis_database(struct vty *vty, const char *sysid_str,
if (vrf_name) { if (vrf_name) {
if (all_vrf) { if (all_vrf) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) 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); ui_level, isis);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
isis = isis_lookup_by_vrfname(vrf_name); isis = isis_lookup_by_vrfname(vrf_name);
if (isis) if (isis)
show_isis_database_common(vty, sysid_str, ui_level, show_isis_database_common(vty, json, sysid_str,
isis); ui_level, isis);
} }
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN(show_database, show_database_cmd, 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 SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
"All VRFs\n" "All VRFs\n"
"Link state database\n" "Link state database\n"
"Detailed information\n" "Detailed information\n"
"LSP ID\n") "LSP ID\n"
"json output\n")
{ {
int res = CMD_SUCCESS;
int idx = 0; int idx = 0;
int idx_vrf = 0; int idx_vrf = 0;
const char *vrf_name = VRF_DEFAULT_NAME; const char *vrf_name = VRF_DEFAULT_NAME;
@ -2765,8 +2845,17 @@ DEFUN(show_database, show_database_cmd,
? ISIS_UI_LEVEL_DETAIL ? ISIS_UI_LEVEL_DETAIL
: ISIS_UI_LEVEL_BRIEF; : ISIS_UI_LEVEL_BRIEF;
char *id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL; 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); 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 #ifdef FABRICD

View file

@ -89,6 +89,8 @@ struct isis_master {
}; };
#define F_ISIS_UNIT_TEST 0x01 #define F_ISIS_UNIT_TEST 0x01
#define ISIS_DEFAULT_MAX_AREA_ADDRESSES 3
struct isis { struct isis {
vrf_id_t vrf_id; vrf_id_t vrf_id;
char *name; char *name;
@ -305,7 +307,11 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
const char *passwd, uint8_t snp_auth); const char *passwd, uint8_t snp_auth);
int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level, int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
const char *passwd, uint8_t snp_auth); const char *passwd, uint8_t snp_auth);
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area, 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, int level, struct lspdb_head *lspdb,
const char *argv, int ui_level); const char *argv, int ui_level);