]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add command to test prefix-list match
authorDavid Lamparter <equinox@opensourcerouting.org>
Tue, 20 Apr 2021 04:13:51 +0000 (06:13 +0200)
committerMartin Winter <mwinter@opensourcerouting.org>
Mon, 5 Jul 2021 23:44:35 +0000 (01:44 +0200)
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>
doc/user/filter.rst
lib/plist.c

index 1fb9beccdc1794f3a527fe65183c93d8ca732e3e..cbbcd47dc37639501682ca29f1b3e9ce659a4d8c 100644 (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
 -------------------------------
 
index 1ee855a594ec4ed863280c3dfe1f3a3ede6bd3bc..2b42c43764ec5b6eb4d674675ea8b49b96d59246 100644 (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);
 }