mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 08:50:26 +00:00
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>
This commit is contained in:
parent
dcf6441e3f
commit
94dc0c4ed4
@ -274,10 +274,29 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
|
|||||||
|
|
||||||
route_unlock_node(rn);
|
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)
|
if (!best)
|
||||||
return rp_info;
|
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;
|
best = rp_info;
|
||||||
|
|
||||||
return best;
|
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;
|
struct rp_info *tmp_rp_info;
|
||||||
char buffer[BUFSIZ];
|
char buffer[BUFSIZ];
|
||||||
struct prefix nht_p;
|
struct prefix nht_p;
|
||||||
struct route_node *rn;
|
struct route_node *rn = NULL;
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
bool upstream_updated = false;
|
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);
|
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)
|
if (PIM_DEBUG_PIM_TRACE)
|
||||||
zlog_debug("Allocated: %p for rp_info: %p(%pFX) Lock: %d", rn,
|
zlog_debug("Allocated: %p for rp_info: %p(%pFX) Lock: %d", rn,
|
||||||
rp_info, &rp_info->group,
|
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) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
if (pim_addr_is_any(up->sg.src)) {
|
if (pim_addr_is_any(up->sg.src)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user