diff options
| author | Donald Sharp <sharpd@nvidia.com> | 2022-05-24 13:33:35 -0400 |
|---|---|---|
| committer | Donald Sharp <sharpd@nvidia.com> | 2022-05-26 10:45:35 -0400 |
| commit | 94dc0c4ed4bbca84ad32cb45bbc492e9cae90d73 (patch) | |
| tree | 287be7af9dbdd0f59323695eefd36ef481e53470 /pimd/pim_rp.c | |
| parent | dcf6441e3f277a3ceeae705232c90ac6345e1d14 (diff) | |
pimd: Allow the LPM match work properly with prefix lists and normal rp's
All rp_info's are being saved in the pim->rp_list and the non prefix-list
rp's are supposed to be saved in table pim->rp_table. What was happening,
though, is that all the plists were being stored at the 224.0.0.0/4 node
of the tree(irrelevant to the fact that we should not be looking up the
non-prefix list rp's in the table) and since we can have multiple prefix lists
and only one rp_info stored at the 224.0.0.0/4 node of the tree, there can be situations
where the 224.0.0.0/4 node can be overwritten due to the order entered.
As such there exists situations where command enter ordering will cause
what we match to, change in pim_rp_find_match_group.
Fixes:
a) Do not store prefix list based rp_info's in the pim->rp_table
b) In pim_rp_find_match_group, ensure that the node lookup does
not correspond to a prefix list based node.
c) When in the situation there are both:
ip pim rp 4.5.6.7 224.0.0.0/16
ip pim rp 5.6.67.8 prefix-list FOO
ip prefix-list FOO permit 224.0.1.0/24
and we receive a group for 224.0.1.5, we were comparing the
224.0.0.0/16 to the 224.0.0.0/4 of the 5.6.67.8 group, when
FRR should have been comparing to entry that matched in the prefix-list
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'pimd/pim_rp.c')
| -rw-r--r-- | pimd/pim_rp.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index fdf4b99c32..3da0a35303 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -274,10 +274,29 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, route_unlock_node(rn); + /* + * rp's with prefix lists have the group as 224.0.0.0/4 which will + * match anything. So if we have a rp_info that should match a prefix + * list then if we do match then best should be the answer( even + * if it is NULL ) + */ + if (!rp_info || (rp_info && rp_info->plist)) + return best; + + /* + * So we have a non plist rp_info found in the lookup and no plists + * at all to be choosen, return it! + */ if (!best) return rp_info; - if (rp_info->group.prefixlen < best->group.prefixlen) + /* + * If we have a matching non prefix list and a matching prefix + * list we should return the actual rp_info that has the LPM + * If they are equal, use the prefix-list( but let's hope + * the end-operator doesn't do this ) + */ + if (rp_info->group.prefixlen > bp->prefixlen) best = rp_info; return best; @@ -423,7 +442,7 @@ int pim_rp_new(struct pim_instance *pim, pim_addr rp_addr, struct prefix group, struct rp_info *tmp_rp_info; char buffer[BUFSIZ]; struct prefix nht_p; - struct route_node *rn; + struct route_node *rn = NULL; struct pim_upstream *up; bool upstream_updated = false; @@ -601,13 +620,16 @@ int pim_rp_new(struct pim_instance *pim, pim_addr rp_addr, struct prefix group, } listnode_add_sort(pim->rp_list, rp_info); - rn = route_node_get(pim->rp_table, &rp_info->group); - rn->info = rp_info; + + if (!rp_info->plist) { + rn = route_node_get(pim->rp_table, &rp_info->group); + rn->info = rp_info; + } if (PIM_DEBUG_PIM_TRACE) zlog_debug("Allocated: %p for rp_info: %p(%pFX) Lock: %d", rn, rp_info, &rp_info->group, - route_node_get_lock_count(rn)); + rn ? route_node_get_lock_count(rn) : 0); frr_each (rb_pim_upstream, &pim->upstream_head, up) { if (pim_addr_is_any(up->sg.src)) { |
