]> git.proxmox.com Git - mirror_frr.git/commitdiff
pim6d: Fixing mroutes not created after disabling and enabling PIMv6.
authorAbhishek N R <abnr@vmware.com>
Fri, 24 Mar 2023 04:55:06 +0000 (21:55 -0700)
committerAbhishek N R <abnr@vmware.com>
Fri, 24 Mar 2023 04:55:06 +0000 (21:55 -0700)
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>
pimd/pim6_mld.c
pimd/pim6_mld.h
pimd/pim_nb_config.c

index fa699cca5e7b7623707f43976c4d234db6f9c7b5..70d057f324a8db2f3e02d105279b80be946f6c78 100644 (file)
@@ -99,7 +99,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;
 }
@@ -182,13 +182,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)
 {
index 2af1c77c24532daf899870873c2206e4929b2885..282fad8a254dde7cae54a9eb6df258e2e66f579d 100644 (file)
@@ -113,6 +113,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:
  *
@@ -352,5 +354,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 */
index fa6f664149570a4182d02dd64849101d11d9289d..c8543ea999b6185600ba52104bea296d7141e38f 100644 (file)
@@ -71,12 +71,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;
@@ -90,6 +97,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
@@ -116,6 +124,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