summaryrefslogtreecommitdiff
path: root/pimd/pim_rp.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2021-04-20 06:11:57 +0200
committerMartin Winter <mwinter@opensourcerouting.org>2021-07-06 01:44:34 +0200
commit2b6b16fc21d35693914231509c8710eff6a58c4a (patch)
tree545863ce2606dff91c0a0dad58b7906ebd55be29 /pimd/pim_rp.c
parentf06c6e3ef91027205e653a4aa72a2bb8969466e9 (diff)
lib, pimd: add address match mode to prefix lists
... the PIM code is kinda misusing prefix lists to match addresses. Considering the weird semantics of access-lists, I can't fault it. However, prefix lists aren't great at matching addresses by default, since they try to match the prefix length too. So, here's an "address match mode" for prefix lists to get that to work more reasonably. Fixes: #8492 Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'pimd/pim_rp.c')
-rw-r--r--pimd/pim_rp.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index b6521132f7..56e1927528 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -204,6 +204,26 @@ static struct rp_info *pim_rp_find_exact(struct pim_instance *pim,
}
/*
+ * XXX: long-term issue: we don't actually have a good "ip address-list"
+ * implementation. ("access-list XYZ" is the closest but honestly it's
+ * kinda garbage.)
+ *
+ * So it's using a prefix-list to match an address here, which causes very
+ * unexpected results for the user since prefix-lists by default only match
+ * when the prefix length is an exact match too. i.e. you'd have to add the
+ * "le 32" and do "ip prefix-list foo permit 10.0.0.0/24 le 32"
+ *
+ * To avoid this pitfall, this code uses "address_mode = true" for the prefix
+ * list match (this is the only user for that.)
+ *
+ * In the long run, we need to add a "ip address-list", but that's a wholly
+ * separate bag of worms, and existing configs using ip prefix-list would
+ * drop into the UX pitfall.
+ */
+
+#include "lib/plist_int.h"
+
+/*
* Given a group, return the rp_info for that group
*/
struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
@@ -213,7 +233,8 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
struct rp_info *best = NULL;
struct rp_info *rp_info;
struct prefix_list *plist;
- const struct prefix *p, *bp;
+ const struct prefix *bp;
+ const struct prefix_list_entry *entry;
struct route_node *rn;
bp = NULL;
@@ -221,19 +242,19 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
if (rp_info->plist) {
plist = prefix_list_lookup(AFI_IP, rp_info->plist);
- if (prefix_list_apply_which_prefix(plist, &p, group)
- == PREFIX_DENY)
+ if (prefix_list_apply_ext(plist, &entry, group, true)
+ == PREFIX_DENY || !entry)
continue;
if (!best) {
best = rp_info;
- bp = p;
+ bp = &entry->prefix;
continue;
}
- if (bp && bp->prefixlen < p->prefixlen) {
+ if (bp && bp->prefixlen < entry->prefix.prefixlen) {
best = rp_info;
- bp = p;
+ bp = &entry->prefix;
}
}
}