lib: add "json" option to "show ip[v6] prefix-list"

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2021-08-02 15:38:26 -03:00
parent c15dc24f79
commit 58e2857d23
2 changed files with 183 additions and 65 deletions

View file

@ -123,19 +123,25 @@ ip prefix-list description
Showing ip prefix-list
----------------------
.. clicmd:: show ip prefix-list
.. clicmd:: show ip prefix-list [json]
Display all IP prefix lists.
.. clicmd:: show ip prefix-list NAME
If the ``json`` option is specified, output is displayed in JSON format.
.. clicmd:: show ip prefix-list NAME [json]
Show IP prefix list can be used with a prefix list name.
.. clicmd:: show ip prefix-list NAME seq NUM
If the ``json`` option is specified, output is displayed in JSON format.
.. clicmd:: show ip prefix-list NAME seq NUM [json]
Show IP prefix list can be used with a prefix list name and sequential
number.
If the ``json`` option is specified, output is displayed in JSON format.
.. clicmd:: show ip prefix-list NAME A.B.C.D/M
If the command longer is used, all prefix lists with prefix lengths equal to
@ -144,10 +150,10 @@ Showing ip prefix-list
.. clicmd:: show ip prefix-list NAME A.B.C.D/M longer
.. clicmd:: show ip prefix-list NAME A.B.C.D/M first-match
.. clicmd:: show ip prefix-list summary
.. clicmd:: show ip prefix-list summary NAME
.. clicmd:: show ip prefix-list detail
.. clicmd:: show ip prefix-list detail NAME
.. clicmd:: show ip prefix-list summary [json]
.. clicmd:: show ip prefix-list summary NAME [json]
.. clicmd:: show ip prefix-list detail [json]
.. clicmd:: show ip prefix-list detail NAME [json]
.. clicmd:: debug prefix-list NAME match <A.B.C.D/M|X:X::X:X/M> [address-mode]

View file

@ -932,46 +932,127 @@ enum display_type {
first_match_display
};
static void vty_show_prefix_entry(struct vty *vty, afi_t afi,
static void vty_show_prefix_entry(struct vty *vty, json_object *json, afi_t afi,
struct prefix_list *plist,
struct prefix_master *master,
enum display_type dtype, int seqnum)
{
struct prefix_list_entry *pentry;
json_object *json_pl = NULL;
/* Print the name of the protocol */
if (json) {
json_pl = json_object_new_object();
json_object_object_add(json, plist->name, json_pl);
} else
vty_out(vty, "%s: ", frr_protoname);
if (dtype == normal_display) {
vty_out(vty, "ip%s prefix-list %s: %d entries\n",
afi == AFI_IP ? "" : "v6", plist->name, plist->count);
if (json) {
json_object_string_add(json_pl, "addressFamily",
afi2str(afi));
json_object_int_add(json_pl, "entries", plist->count);
if (plist->desc)
vty_out(vty, " Description: %s\n", plist->desc);
json_object_string_add(json_pl, "description",
plist->desc);
} else {
vty_out(vty, "ip%s prefix-list %s: %d entries\n",
afi == AFI_IP ? "" : "v6", plist->name,
plist->count);
if (plist->desc)
vty_out(vty, " Description: %s\n",
plist->desc);
}
} else if (dtype == summary_display || dtype == detail_display) {
if (json) {
json_object_string_add(json_pl, "addressFamily",
afi2str(afi));
if (plist->desc)
json_object_string_add(json_pl, "description",
plist->desc);
json_object_int_add(json_pl, "count", plist->count);
json_object_int_add(json_pl, "rangeEntries",
plist->rangecount);
json_object_int_add(json_pl, "sequenceStart",
plist->head ? plist->head->seq : 0);
json_object_int_add(json_pl, "sequenceEnd",
plist->tail ? plist->tail->seq : 0);
} else {
vty_out(vty, "ip%s prefix-list %s:\n",
afi == AFI_IP ? "" : "v6", plist->name);
if (plist->desc)
vty_out(vty, " Description: %s\n", plist->desc);
vty_out(vty, " Description: %s\n",
plist->desc);
vty_out(vty,
" count: %d, range entries: %d, sequences: %" PRId64 " - %" PRId64 "\n",
" count: %d, range entries: %d, sequences: %" PRId64
" - %" PRId64 "\n",
plist->count, plist->rangecount,
plist->head ? plist->head->seq : 0,
plist->tail ? plist->tail->seq : 0);
}
}
if (dtype != summary_display) {
json_object *json_entries = NULL;
if (json) {
json_entries = json_object_new_array();
json_object_object_add(json_pl, "entries",
json_entries);
}
for (pentry = plist->head; pentry; pentry = pentry->next) {
if (dtype == sequential_display
&& pentry->seq != seqnum)
continue;
if (json) {
json_object *json_entry;
char buf[BUFSIZ];
json_entry = json_object_new_object();
json_object_array_add(json_entries, json_entry);
json_object_int_add(json_entry,
"sequenceNumber",
pentry->seq);
json_object_string_add(
json_entry, "type",
prefix_list_type_str(pentry));
json_object_string_add(
json_entry, "prefix",
prefix2str(&pentry->prefix, buf,
sizeof(buf)));
if (pentry->ge)
json_object_int_add(
json_entry,
"minimumPrefixLength",
pentry->ge);
if (pentry->le)
json_object_int_add(
json_entry,
"maximumPrefixLength",
pentry->le);
if (dtype == detail_display
|| dtype == sequential_display) {
json_object_int_add(json_entry,
"hitCount",
pentry->hitcnt);
json_object_int_add(json_entry,
"referenceCount",
pentry->refcnt);
}
} else {
vty_out(vty, " ");
vty_out(vty, "seq %" PRId64 " ", pentry->seq);
vty_out(vty, "%s ", prefix_list_type_str(pentry));
vty_out(vty, "%s ",
prefix_list_type_str(pentry));
if (pentry->any)
vty_out(vty, "any");
@ -981,53 +1062,76 @@ static void vty_show_prefix_entry(struct vty *vty, afi_t afi,
vty_out(vty, "%pFX", p);
if (pentry->ge)
vty_out(vty, " ge %d", pentry->ge);
vty_out(vty, " ge %d",
pentry->ge);
if (pentry->le)
vty_out(vty, " le %d", pentry->le);
vty_out(vty, " le %d",
pentry->le);
}
if (dtype == detail_display
|| dtype == sequential_display)
vty_out(vty, " (hit count: %ld, refcount: %ld)",
vty_out(vty,
" (hit count: %ld, refcount: %ld)",
pentry->hitcnt, pentry->refcnt);
vty_out(vty, "\n");
}
}
}
}
static int vty_show_prefix_list(struct vty *vty, afi_t afi, const char *name,
const char *seq, enum display_type dtype)
const char *seq, enum display_type dtype,
bool uj)
{
struct prefix_list *plist;
struct prefix_master *master;
int64_t seqnum = 0;
json_object *json = NULL;
json_object *json_proto = NULL;
master = prefix_master_get(afi, 0);
if (master == NULL)
return CMD_WARNING;
if (uj) {
json = json_object_new_object();
json_proto = json_object_new_object();
json_object_object_add(json, frr_protoname, json_proto);
}
if (seq)
seqnum = (int64_t)atol(seq);
if (name) {
plist = prefix_list_lookup(afi, name);
if (!plist) {
vty_out(vty, "%% Can't find specified prefix-list\n");
if (!uj)
vty_out(vty,
"%% Can't find specified prefix-list\n");
return CMD_WARNING;
}
vty_show_prefix_entry(vty, afi, plist, master, dtype, seqnum);
vty_show_prefix_entry(vty, json_proto, afi, plist, master,
dtype, seqnum);
} else {
if (dtype == detail_display || dtype == summary_display) {
if (master->recent)
if (master->recent && !uj)
vty_out(vty,
"Prefix-list with the last deletion/insertion: %s\n",
master->recent->name);
}
for (plist = master->str.head; plist; plist = plist->next)
vty_show_prefix_entry(vty, afi, plist, master, dtype,
seqnum);
vty_show_prefix_entry(vty, json_proto, afi, plist,
master, dtype, seqnum);
}
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;
@ -1150,19 +1254,21 @@ static int vty_clear_prefix_list(struct vty *vty, afi_t afi, const char *name,
DEFPY (show_ip_prefix_list,
show_ip_prefix_list_cmd,
"show ip prefix-list [WORD [seq$dseq (1-4294967295)$arg]]",
"show ip prefix-list [WORD [seq$dseq (1-4294967295)$arg]] [json$uj]",
SHOW_STR
IP_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
"sequence number of an entry\n"
"Sequence number\n")
"Sequence number\n"
JSON_STR)
{
enum display_type dtype = normal_display;
if (dseq)
dtype = sequential_display;
return vty_show_prefix_list(vty, AFI_IP, prefix_list, arg_str, dtype);
return vty_show_prefix_list(vty, AFI_IP, prefix_list, arg_str, dtype,
!!uj);
}
DEFPY (show_ip_prefix_list_prefix,
@ -1188,28 +1294,30 @@ DEFPY (show_ip_prefix_list_prefix,
DEFPY (show_ip_prefix_list_summary,
show_ip_prefix_list_summary_cmd,
"show ip prefix-list summary [WORD$prefix_list]",
"show ip prefix-list summary [WORD$prefix_list] [json$uj]",
SHOW_STR
IP_STR
PREFIX_LIST_STR
"Summary of prefix lists\n"
"Name of a prefix list\n")
"Name of a prefix list\n"
JSON_STR)
{
return vty_show_prefix_list(vty, AFI_IP, prefix_list, NULL,
summary_display);
summary_display, !!uj);
}
DEFPY (show_ip_prefix_list_detail,
show_ip_prefix_list_detail_cmd,
"show ip prefix-list detail [WORD$prefix_list]",
"show ip prefix-list detail [WORD$prefix_list] [json$uj]",
SHOW_STR
IP_STR
PREFIX_LIST_STR
"Detail of prefix lists\n"
"Name of a prefix list\n")
"Name of a prefix list\n"
JSON_STR)
{
return vty_show_prefix_list(vty, AFI_IP, prefix_list, NULL,
detail_display);
detail_display, !!uj);
}
DEFPY (clear_ip_prefix_list,
@ -1226,19 +1334,21 @@ DEFPY (clear_ip_prefix_list,
DEFPY (show_ipv6_prefix_list,
show_ipv6_prefix_list_cmd,
"show ipv6 prefix-list [WORD [seq$dseq (1-4294967295)$arg]]",
"show ipv6 prefix-list [WORD [seq$dseq (1-4294967295)$arg]] [json$uj]",
SHOW_STR
IPV6_STR
PREFIX_LIST_STR
"Name of a prefix list\n"
"sequence number of an entry\n"
"Sequence number\n")
"Sequence number\n"
JSON_STR)
{
enum display_type dtype = normal_display;
if (dseq)
dtype = sequential_display;
return vty_show_prefix_list(vty, AFI_IP6, prefix_list, arg_str, dtype);
return vty_show_prefix_list(vty, AFI_IP6, prefix_list, arg_str, dtype,
!!uj);
}
DEFPY (show_ipv6_prefix_list_prefix,
@ -1264,28 +1374,30 @@ DEFPY (show_ipv6_prefix_list_prefix,
DEFPY (show_ipv6_prefix_list_summary,
show_ipv6_prefix_list_summary_cmd,
"show ipv6 prefix-list summary [WORD$prefix-list]",
"show ipv6 prefix-list summary [WORD$prefix-list] [json$uj]",
SHOW_STR
IPV6_STR
PREFIX_LIST_STR
"Summary of prefix lists\n"
"Name of a prefix list\n")
"Name of a prefix list\n"
JSON_STR)
{
return vty_show_prefix_list(vty, AFI_IP6, prefix_list, NULL,
summary_display);
summary_display, !!uj);
}
DEFPY (show_ipv6_prefix_list_detail,
show_ipv6_prefix_list_detail_cmd,
"show ipv6 prefix-list detail [WORD$prefix-list]",
"show ipv6 prefix-list detail [WORD$prefix-list] [json$uj]",
SHOW_STR
IPV6_STR
PREFIX_LIST_STR
"Detail of prefix lists\n"
"Name of a prefix list\n")
"Name of a prefix list\n"
JSON_STR)
{
return vty_show_prefix_list(vty, AFI_IP6, prefix_list, NULL,
detail_display);
detail_display, !!uj);
}
DEFPY (clear_ipv6_prefix_list,