lib: add command to test prefix-list match

While we do have `show ip prefix-list NAME A.B.C.D/M`, that doesn't
actually run the prefix list matching code.  While the result would
hopefully be the same anyway, let's have a way to call the actual prefix
list match code and get a result.

(As an aside, this might be useful for scripting to do a quick "is this
prefix in that prefix list" check.)

Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
David Lamparter 2021-04-20 06:13:51 +02:00 committed by Martin Winter
parent 2b6b16fc21
commit 19cf3fc5ab
No known key found for this signature in database
GPG Key ID: 05A4ECF8C0102306
2 changed files with 55 additions and 0 deletions

View File

@ -137,6 +137,15 @@ Showing ip prefix-list
.. clicmd:: show ip prefix-list detail
.. clicmd:: show ip prefix-list detail NAME
.. clicmd:: debug prefix-list NAME match <A.B.C.D/M|X:X::X:X/M> [address-mode]
Execute the prefix list matching code for the specified list and prefix.
Shows which entry matched, if any. (``address-mode`` is used for
PIM RP lookups and skips prefix length checks.)
The return value from this command is success only if the prefix-list
result is to permit the prefix, so the command can be used in scripting.
Clear counter of ip prefix-list
-------------------------------

View File

@ -1300,6 +1300,51 @@ DEFPY (clear_ipv6_prefix_list,
return vty_clear_prefix_list(vty, AFI_IP6, prefix_list, prefix_str);
}
DEFPY (debug_prefix_list_match,
debug_prefix_list_match_cmd,
"debug prefix-list WORD$prefix-list match <A.B.C.D/M|X:X::X:X/M>"
" [address-mode$addr_mode]",
DEBUG_STR
"Prefix-list test access\n"
"Name of a prefix list\n"
"Test prefix for prefix list result\n"
"Prefix to test in ip prefix-list\n"
"Prefix to test in ipv6 prefix-list\n"
"Use address matching mode (PIM RP)\n")
{
struct prefix_list *plist;
const struct prefix_list_entry *entry = NULL;
enum prefix_list_type ret;
plist = prefix_list_lookup(family2afi(match->family), prefix_list);
if (!plist) {
vty_out(vty, "%% no prefix list named %s for AFI %s\n",
prefix_list, afi2str(family2afi(match->family)));
return CMD_WARNING;
}
ret = prefix_list_apply_ext(plist, &entry, match, !!addr_mode);
vty_out(vty, "%s prefix list %s yields %s for %pFX, ",
afi2str(family2afi(match->family)), prefix_list,
ret == PREFIX_DENY ? "DENY" : "PERMIT", match);
if (!entry)
vty_out(vty, "no match found\n");
else {
vty_out(vty, "matching entry #%"PRId64": %pFX", entry->seq,
&entry->prefix);
if (entry->ge)
vty_out(vty, " ge %d", entry->ge);
if (entry->le)
vty_out(vty, " le %d", entry->le);
vty_out(vty, "\n");
}
/* allow using this in scripts for quick prefix-list member tests */
return (ret == PREFIX_PERMIT) ? CMD_SUCCESS : CMD_WARNING;
}
struct stream *prefix_bgp_orf_entry(struct stream *s, struct prefix_list *plist,
uint8_t init_flag, uint8_t permit_flag,
uint8_t deny_flag)
@ -1541,6 +1586,7 @@ static void prefix_list_init_ipv6(void)
install_element(VIEW_NODE, &show_ipv6_prefix_list_prefix_cmd);
install_element(VIEW_NODE, &show_ipv6_prefix_list_summary_cmd);
install_element(VIEW_NODE, &show_ipv6_prefix_list_detail_cmd);
install_element(VIEW_NODE, &debug_prefix_list_match_cmd);
install_element(ENABLE_NODE, &clear_ipv6_prefix_list_cmd);
}