pim6d: Fixing mroutes not created after disabling and enabling PIMv6.

After doing "no ipv6 pim" and "ipv6 pim" on receiver interface in LHR,
mroutes were not created.

When we enable pim after disabling it, we refresh the membership on pim interface.
First we clear the membership on the interface, then we add it back.
For PIMv6 we were only clearing it, membership was not added back. So mroutes were not created.

Now added code to fetch all the local membership information into PIM.

Fixes: #12005, #12820

Signed-off-by: Abhishek N R <abnr@vmware.com>
(cherry picked from commit 00fed6ed3b)
This commit is contained in:
Abhishek N R 2023-03-23 21:55:06 -07:00 committed by Mergify
parent 6398f44245
commit ce8a824d5d
3 changed files with 24 additions and 5 deletions

View File

@ -112,7 +112,7 @@ static inline uint8_t in6_multicast_scope(const pim_addr *addr)
return addr->s6_addr[1] & 0xf;
}
static inline bool in6_multicast_nofwd(const pim_addr *addr)
bool in6_multicast_nofwd(const pim_addr *addr)
{
return in6_multicast_scope(addr) <= IPV6_MULTICAST_SCOPE_LINK;
}
@ -195,13 +195,11 @@ DECLARE_HASH(gm_gsq_pends, struct gm_gsq_pending, itm, gm_gsq_pending_cmp,
* interface -> (S,G)
*/
static int gm_sg_cmp(const struct gm_sg *a, const struct gm_sg *b)
int gm_sg_cmp(const struct gm_sg *a, const struct gm_sg *b)
{
return pim_sgaddr_cmp(a->sgaddr, b->sgaddr);
}
DECLARE_RBTREE_UNIQ(gm_sgs, struct gm_sg, itm, gm_sg_cmp);
static struct gm_sg *gm_sg_find(struct gm_if *gm_ifp, pim_addr grp,
pim_addr src)
{

View File

@ -126,6 +126,8 @@ struct gm_sg {
*/
struct gm_packet_sg *most_recent;
};
int gm_sg_cmp(const struct gm_sg *a, const struct gm_sg *b);
DECLARE_RBTREE_UNIQ(gm_sgs, struct gm_sg, itm, gm_sg_cmp);
/* host tracking entry. addr will be one of:
*
@ -365,5 +367,6 @@ static inline void gm_ifp_teardown(struct interface *ifp)
#endif
extern void gm_cli_init(void);
bool in6_multicast_nofwd(const pim_addr *addr);
#endif /* PIM6_MLD_H */

View File

@ -84,12 +84,19 @@ static void pim_if_membership_clear(struct interface *ifp)
static void pim_if_membership_refresh(struct interface *ifp)
{
struct pim_interface *pim_ifp;
#if PIM_IPV == 4
struct listnode *grpnode;
struct gm_group *grp;
#else
struct gm_if *gm_ifp;
struct gm_sg *sg, *sg_start;
#endif
pim_ifp = ifp->info;
assert(pim_ifp);
#if PIM_IPV == 6
gm_ifp = pim_ifp->mld;
#endif
if (!pim_ifp->pim_enable)
return;
@ -103,6 +110,7 @@ static void pim_if_membership_refresh(struct interface *ifp)
pim_ifchannel_membership_clear(ifp);
#if PIM_IPV == 4
/*
* Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
* the interface
@ -129,6 +137,16 @@ static void pim_if_membership_refresh(struct interface *ifp)
} /* scan group sources */
} /* scan igmp groups */
#else
sg_start = gm_sgs_first(gm_ifp->sgs);
frr_each_from (gm_sgs, gm_ifp->sgs, sg, sg_start) {
if (!in6_multicast_nofwd(&sg->sgaddr.grp)) {
pim_ifchannel_local_membership_add(
ifp, &sg->sgaddr, false /*is_vxlan*/);
}
}
#endif
/*
* Finally delete every PIM (S,G) entry lacking all state info