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 Showing ip prefix-list
---------------------- ----------------------
.. clicmd:: show ip prefix-list .. clicmd:: show ip prefix-list [json]
Display all IP prefix lists. 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. 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 Show IP prefix list can be used with a prefix list name and sequential
number. number.
If the ``json`` option is specified, output is displayed in JSON format.
.. clicmd:: show ip prefix-list NAME A.B.C.D/M .. 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 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 longer
.. clicmd:: show ip prefix-list NAME A.B.C.D/M first-match .. 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 [json]
.. clicmd:: show ip prefix-list summary NAME .. clicmd:: show ip prefix-list summary NAME [json]
.. clicmd:: show ip prefix-list detail .. clicmd:: show ip prefix-list detail [json]
.. clicmd:: show ip prefix-list detail NAME .. 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] .. 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 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_list *plist,
struct prefix_master *master, struct prefix_master *master,
enum display_type dtype, int seqnum) enum display_type dtype, int seqnum)
{ {
struct prefix_list_entry *pentry; struct prefix_list_entry *pentry;
json_object *json_pl = NULL;
/* Print the name of the protocol */ /* 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); vty_out(vty, "%s: ", frr_protoname);
if (dtype == normal_display) { if (dtype == normal_display) {
vty_out(vty, "ip%s prefix-list %s: %d entries\n", if (json) {
afi == AFI_IP ? "" : "v6", plist->name, plist->count); json_object_string_add(json_pl, "addressFamily",
afi2str(afi));
json_object_int_add(json_pl, "entries", plist->count);
if (plist->desc) 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) { } 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", vty_out(vty, "ip%s prefix-list %s:\n",
afi == AFI_IP ? "" : "v6", plist->name); afi == AFI_IP ? "" : "v6", plist->name);
if (plist->desc) if (plist->desc)
vty_out(vty, " Description: %s\n", plist->desc); vty_out(vty, " Description: %s\n",
plist->desc);
vty_out(vty, 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->count, plist->rangecount,
plist->head ? plist->head->seq : 0, plist->head ? plist->head->seq : 0,
plist->tail ? plist->tail->seq : 0); plist->tail ? plist->tail->seq : 0);
} }
}
if (dtype != summary_display) { 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) { for (pentry = plist->head; pentry; pentry = pentry->next) {
if (dtype == sequential_display if (dtype == sequential_display
&& pentry->seq != seqnum) && pentry->seq != seqnum)
continue; 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, " ");
vty_out(vty, "seq %" PRId64 " ", pentry->seq); 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) if (pentry->any)
vty_out(vty, "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); vty_out(vty, "%pFX", p);
if (pentry->ge) if (pentry->ge)
vty_out(vty, " ge %d", pentry->ge); vty_out(vty, " ge %d",
pentry->ge);
if (pentry->le) if (pentry->le)
vty_out(vty, " le %d", pentry->le); vty_out(vty, " le %d",
pentry->le);
} }
if (dtype == detail_display if (dtype == detail_display
|| dtype == sequential_display) || dtype == sequential_display)
vty_out(vty, " (hit count: %ld, refcount: %ld)", vty_out(vty,
" (hit count: %ld, refcount: %ld)",
pentry->hitcnt, pentry->refcnt); pentry->hitcnt, pentry->refcnt);
vty_out(vty, "\n"); vty_out(vty, "\n");
} }
} }
}
} }
static int vty_show_prefix_list(struct vty *vty, afi_t afi, const char *name, 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_list *plist;
struct prefix_master *master; struct prefix_master *master;
int64_t seqnum = 0; int64_t seqnum = 0;
json_object *json = NULL;
json_object *json_proto = NULL;
master = prefix_master_get(afi, 0); master = prefix_master_get(afi, 0);
if (master == NULL) if (master == NULL)
return CMD_WARNING; 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) if (seq)
seqnum = (int64_t)atol(seq); seqnum = (int64_t)atol(seq);
if (name) { if (name) {
plist = prefix_list_lookup(afi, name); plist = prefix_list_lookup(afi, name);
if (!plist) { 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; 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 { } else {
if (dtype == detail_display || dtype == summary_display) { if (dtype == detail_display || dtype == summary_display) {
if (master->recent) if (master->recent && !uj)
vty_out(vty, vty_out(vty,
"Prefix-list with the last deletion/insertion: %s\n", "Prefix-list with the last deletion/insertion: %s\n",
master->recent->name); master->recent->name);
} }
for (plist = master->str.head; plist; plist = plist->next) for (plist = master->str.head; plist; plist = plist->next)
vty_show_prefix_entry(vty, afi, plist, master, dtype, vty_show_prefix_entry(vty, json_proto, afi, plist,
seqnum); 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; 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, DEFPY (show_ip_prefix_list,
show_ip_prefix_list_cmd, 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 SHOW_STR
IP_STR IP_STR
PREFIX_LIST_STR PREFIX_LIST_STR
"Name of a prefix list\n" "Name of a prefix list\n"
"sequence number of an entry\n" "sequence number of an entry\n"
"Sequence number\n") "Sequence number\n"
JSON_STR)
{ {
enum display_type dtype = normal_display; enum display_type dtype = normal_display;
if (dseq) if (dseq)
dtype = sequential_display; 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, DEFPY (show_ip_prefix_list_prefix,
@ -1188,28 +1294,30 @@ DEFPY (show_ip_prefix_list_prefix,
DEFPY (show_ip_prefix_list_summary, DEFPY (show_ip_prefix_list_summary,
show_ip_prefix_list_summary_cmd, 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 SHOW_STR
IP_STR IP_STR
PREFIX_LIST_STR PREFIX_LIST_STR
"Summary of prefix lists\n" "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, return vty_show_prefix_list(vty, AFI_IP, prefix_list, NULL,
summary_display); summary_display, !!uj);
} }
DEFPY (show_ip_prefix_list_detail, DEFPY (show_ip_prefix_list_detail,
show_ip_prefix_list_detail_cmd, 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 SHOW_STR
IP_STR IP_STR
PREFIX_LIST_STR PREFIX_LIST_STR
"Detail of prefix lists\n" "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, return vty_show_prefix_list(vty, AFI_IP, prefix_list, NULL,
detail_display); detail_display, !!uj);
} }
DEFPY (clear_ip_prefix_list, DEFPY (clear_ip_prefix_list,
@ -1226,19 +1334,21 @@ DEFPY (clear_ip_prefix_list,
DEFPY (show_ipv6_prefix_list, DEFPY (show_ipv6_prefix_list,
show_ipv6_prefix_list_cmd, 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 SHOW_STR
IPV6_STR IPV6_STR
PREFIX_LIST_STR PREFIX_LIST_STR
"Name of a prefix list\n" "Name of a prefix list\n"
"sequence number of an entry\n" "sequence number of an entry\n"
"Sequence number\n") "Sequence number\n"
JSON_STR)
{ {
enum display_type dtype = normal_display; enum display_type dtype = normal_display;
if (dseq) if (dseq)
dtype = sequential_display; 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, DEFPY (show_ipv6_prefix_list_prefix,
@ -1264,28 +1374,30 @@ DEFPY (show_ipv6_prefix_list_prefix,
DEFPY (show_ipv6_prefix_list_summary, DEFPY (show_ipv6_prefix_list_summary,
show_ipv6_prefix_list_summary_cmd, 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 SHOW_STR
IPV6_STR IPV6_STR
PREFIX_LIST_STR PREFIX_LIST_STR
"Summary of prefix lists\n" "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, return vty_show_prefix_list(vty, AFI_IP6, prefix_list, NULL,
summary_display); summary_display, !!uj);
} }
DEFPY (show_ipv6_prefix_list_detail, DEFPY (show_ipv6_prefix_list_detail,
show_ipv6_prefix_list_detail_cmd, 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 SHOW_STR
IPV6_STR IPV6_STR
PREFIX_LIST_STR PREFIX_LIST_STR
"Detail of prefix lists\n" "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, return vty_show_prefix_list(vty, AFI_IP6, prefix_list, NULL,
detail_display); detail_display, !!uj);
} }
DEFPY (clear_ipv6_prefix_list, DEFPY (clear_ipv6_prefix_list,