summaryrefslogtreecommitdiffstats
path: root/pimd
diff options
context:
space:
mode:
authorMobashshera Rasool <mrasool@vmware.com>2023-06-22 09:56:31 +0200
committerMobashshera Rasool <mrasool@vmware.com>2023-06-26 16:45:30 +0200
commit7de521470f0f82db4bd0cfcbe45761b909934639 (patch)
treeb03ca24c2764fcc78b42a90a033be6825dd37ae9 /pimd
parentMerge pull request #13771 from mjstapp/opaque_notify (diff)
downloadfrr-7de521470f0f82db4bd0cfcbe45761b909934639.tar.xz
frr-7de521470f0f82db4bd0cfcbe45761b909934639.zip
pim6d: MLD conformance querier-non-querier transition fix
Problem: ANVL Conformance test case 7.31 failed because DUT after receiving MLD Done msg and a query message with lower adddress, DUT did not keep on sending the group specific queries since it moved to non-querier state. As per RFC 2710 s4 p7, DUT is supposed to keep sending the group specific queries until either it receives the membership report or there is no response even after last member query is sent. Fix: Whenever group specific queries are sent out we are checking if the self node is querier, if not it does not sends this query out. This check is preventing the continuation of the last queries which must be sent out although the self node is not the querier. Hence removing the check from the api gm_trigger_specific_query and adding in the caller to make sure this event is only added for queriers. This will make sure the last member queries are sent out even during the transition phase. Also earlier this event was getting added for non-querier as well which is redundant since queries were not required to be sent out by non-queriers. Issue: #13539 Signed-off-by: Mobashshera Rasool <mrasool@vmware.com>
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim6_mld.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/pimd/pim6_mld.c b/pimd/pim6_mld.c
index aa39be63d..52496325c 100644
--- a/pimd/pim6_mld.c
+++ b/pimd/pim6_mld.c
@@ -355,6 +355,7 @@ static const char *const gm_states[] = {
static void gm_sg_update(struct gm_sg *sg, bool has_expired)
{
struct gm_if *gm_ifp = sg->iface;
+ struct pim_interface *pim_ifp = gm_ifp->ifp->info;
enum gm_sg_state prev, desired;
bool new_join;
struct gm_sg *grp = NULL;
@@ -404,9 +405,12 @@ static void gm_sg_update(struct gm_sg *sg, bool has_expired)
gm_sg_timer_start(gm_ifp, sg, timers.expire_wait);
EVENT_OFF(sg->t_sg_query);
- sg->n_query = gm_ifp->cur_lmqc;
sg->query_sbit = false;
- gm_trigger_specific(sg);
+ /* Trigger the specific queries only for querier. */
+ if (IPV6_ADDR_SAME(&gm_ifp->querier, &pim_ifp->ll_lowest)) {
+ sg->n_query = gm_ifp->cur_lmqc;
+ gm_trigger_specific(sg);
+ }
}
}
prev = sg->state;
@@ -1924,7 +1928,6 @@ static void gm_t_gsq_pend(struct event *t)
static void gm_trigger_specific(struct gm_sg *sg)
{
struct gm_if *gm_ifp = sg->iface;
- struct pim_interface *pim_ifp = gm_ifp->ifp->info;
struct gm_gsq_pending *pend_gsq, ref = {};
sg->n_query--;
@@ -1933,8 +1936,20 @@ static void gm_trigger_specific(struct gm_sg *sg)
gm_ifp->cur_query_intv_trig,
&sg->t_sg_query);
- if (!IPV6_ADDR_SAME(&gm_ifp->querier, &pim_ifp->ll_lowest))
- return;
+ /* As per RFC 2271, s6 p14:
+ * E.g. a router that starts as a Querier, receives a
+ * Done message for a group and then receives a Query from a router with
+ * a lower address (causing a transition to the Non-Querier state)
+ * continues to send multicast-address-specific queries for the group in
+ * question until it either receives a Report or its timer expires, at
+ * which time it starts performing the actions of a Non-Querier for this
+ * group.
+ */
+ /* Therefore here we do not need to check if this router is querier or
+ * not. This is called only for querier, hence it will work even if the
+ * router transitions from querier to non-querier.
+ */
+
if (gm_ifp->pim->gm_socket == -1)
return;