]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pim6d: Fixing core while running MLD conformance test.
authorAbhishek N R <abnr@vmware.com>
Thu, 13 Jul 2023 09:54:27 +0000 (02:54 -0700)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Thu, 20 Jul 2023 12:24:12 +0000 (12:24 +0000)
While running MLD conformance test 9.2 core is getting generated.

Test setps:
1. ANVL: Listen (for upto <GeneralQueryRecvWaitTime> seconds) on <AIface-0>.
2. DUT: Send MLD General Query Message.
3. ANVL: Send MLD Report Message to <DIface-0> containing:
• IPv6 Source Address field set to link-local IPv6 Address of HOST-1
• IPv6 Destination Address field set to <McastAddrGroup>
• MLD Multicast Address field set to <McastAddrGroup>.
4. ANVL: Wait for <ProcessTime> seconds for DUT to process and add <Mcas- tAddrGroup> to its Multicast Address list.
5. ANVL: Send MLD General Query Message to <DIface-0> containing:
• IPv6 Source Address field set to link-local IPv6 Address of RTR-1 which is numerically less than the link-local IPv6 unicast address of <DIface-0>
• IPv6 Destination Address field set to link-scope all-nodes multicast address.
6. ANVL: Send MLD Multicast-Address-Specific Query Message to <DIface-0> containing:
• IPv6 Source Address field set to link-local IPv6 Address of RTR-1
• IPv6 Destination Address field set to <McastAddrGroup>
• MLD Multicast Address field set to <McastAddrGroup>
• MLD Maximum Response Delay field value set to 0.
7. ANVL: Verify that the Maximum Response Delay timer for <McastAd- drGroup> is set to zero.

While running above test, when group specific query is received we start gm_t_sg_expire timer.
Once this timer expires, we clear the corresponding entry.
During this sg->state was still set to JOIN. This happened because receiver went down without sending leave.

Added a condition to update the sg->state before starting the timer.
If receiver goes down without sending leave we will update sg->state to GM_SG_JOIN_EXPIRING or GM_SG_NOPRUNE_EXPIRING based on previous state.
If we receive a join then sg->state will be refreshed and will be updated to JOIN state.

Fixes: #13387
Signed-off-by: Abhishek N R <abnr@vmware.com>
(cherry picked from commit e9484001ee2a1030228de39c997e19f90e32516b)

pimd/pim6_mld.c
pimd/pim6_mld.h

index aa39be63dbbb00e0ffb50b12695214849eef58c1..e11d7c745a6a24a33dab758f0d9031afff1ab9cc 100644 (file)
@@ -1239,6 +1239,7 @@ static void gm_handle_q_groupsrc(struct gm_if *gm_ifp,
 
        for (i = 0; i < n_src; i++) {
                sg = gm_sg_find(gm_ifp, grp, srcs[i]);
+               GM_UPDATE_SG_STATE(sg);
                gm_sg_timer_start(gm_ifp, sg, timers->expire_wait);
        }
 }
@@ -1313,6 +1314,7 @@ static void gm_handle_q_group(struct gm_if *gm_ifp,
                if (PIM_DEBUG_GM_TRACE)
                        zlog_debug(log_ifp("*,%pPAs expiry timer starting"),
                                   &grp);
+               GM_UPDATE_SG_STATE(sg);
                gm_sg_timer_start(gm_ifp, sg, timers->expire_wait);
 
                sg = gm_sgs_next(gm_ifp->sgs, sg);
index 7634fb2ec4537c5dd888bffa996ccdf978f2fba4..183ab2fc508d487e948f665079e6ea133bfa40b0 100644 (file)
@@ -36,6 +36,21 @@ enum gm_sg_state {
        GM_SG_NOPRUNE_EXPIRING,
 };
 
+/* If the timer gm_t_sg_expire is started without a leave message being received,
+ * the sg->state should be moved to expiring states.
+ * When the timer expires, we do not expect the state to be in join state.
+ * If a JOIN message is received while the timer is running,
+ * the state will be moved to JOIN and this timer will be switched off.
+ * Hence the below state transition is done.
+ */
+#define GM_UPDATE_SG_STATE(sg)                                                 \
+       do {                                                                   \
+               if (sg->state == GM_SG_JOIN)                                   \
+                       sg->state = GM_SG_JOIN_EXPIRING;                       \
+               else if (sg->state == GM_SG_NOPRUNE)                           \
+                       sg->state = GM_SG_NOPRUNE_EXPIRING;                    \
+       } while (0)
+
 static inline bool gm_sg_state_want_join(enum gm_sg_state state)
 {
        return state != GM_SG_NOINFO && state != GM_SG_PRUNE;