mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 15:10:38 +00:00
pimd: fix problem with oif being re-added during ifchannel del
Series of events leading to the problem - 1. (S,G) has been pruned on the rp on downlink-1 2. a (*,G) join is rxed on downlink-1 without the source S. This results in the (S,G,rpt) prune state being cleared on downlink-1. As a part of the clear the ifchannel associated with downlink-1 is deleted. 3. The ifchannel_delete handling is expected to add downlink-1 as an inherited OIF to the channel OIL (which it does). However it is also added in as an immediate OIF (accidentally) as the ifchannel is still present (in the process of being deleted). To avoid the problem defer pim_upstream_update_join_desired evaluation until after the channel is deleted. Relevant debug logs - PIM: pim_ifchannel_delete: ifchannel entry (27.0.0.15,239.1.1.106)(downlink-1) del start PIM: pim_channel_add_oif(pim_ifchannel_delete): (S,G)=(27.0.0.15,239.1.1.106): proto_mask=4 OIF=downlink-1 vif_index=7: DONE PIM: pimd/pim_oil.c pim_channel_del_oif: no existing protocol mask 2(4) for requested OIF downlink-1 (vif_index=7, min_ttl=1) for channel (S,G)=(27.0.0.15,239.1.1.106) PIM: pim_upstream_switch: PIM_UPSTREAM_(27.0.0.15,239.1.1.106): (S,G) old: NotJoined new: Joined PIM: pim_channel_add_oif(pim_upstream_inherited_olist_decide): (S,G)=(27.0.0.15,239.1.1.106): proto_mask=2 OIF=downlink-1 vif_index=7 added to 0x6 >>>>>>>>>>>>>>>>>> PIM: pim_upstream_del(pim_ifchannel_delete): Delete (27.0.0.15,239.1.1.106)[default] ref count: 2 , flags: 81 c_oil ref count 1 (Pre decrement) PIM: pim_ifchannel_delete: ifchannel entry (27.0.0.15,239.1.1.106)(downlink-1) del end Ticket: CM-26732 Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
parent
b900ad16ee
commit
0f31a82a11
@ -128,6 +128,7 @@ static void pim_ifchannel_find_new_children(struct pim_ifchannel *ch)
|
||||
void pim_ifchannel_delete(struct pim_ifchannel *ch)
|
||||
{
|
||||
struct pim_interface *pim_ifp;
|
||||
struct pim_upstream *up;
|
||||
|
||||
pim_ifp = ch->interface->info;
|
||||
|
||||
@ -201,14 +202,14 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
|
||||
|
||||
listnode_delete(ch->upstream->ifchannels, ch);
|
||||
|
||||
pim_upstream_update_join_desired(pim_ifp->pim, ch->upstream);
|
||||
up = ch->upstream;
|
||||
|
||||
/* upstream is common across ifchannels, check if upstream's
|
||||
ifchannel list is empty before deleting upstream_del
|
||||
ref count will take care of it.
|
||||
*/
|
||||
if (ch->upstream->ref_count > 0)
|
||||
pim_upstream_del(pim_ifp->pim, ch->upstream, __func__);
|
||||
up = pim_upstream_del(pim_ifp->pim, ch->upstream, __func__);
|
||||
|
||||
else {
|
||||
if (PIM_DEBUG_PIM_TRACE)
|
||||
@ -237,6 +238,9 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
|
||||
ch->sg_str);
|
||||
|
||||
XFREE(MTYPE_PIM_IFCHANNEL, ch);
|
||||
|
||||
if (up)
|
||||
pim_upstream_update_join_desired(pim_ifp->pim, up);
|
||||
}
|
||||
|
||||
void pim_ifchannel_delete_all(struct interface *ifp)
|
||||
|
Loading…
Reference in New Issue
Block a user