diff options
author | Mobashshera Rasool <mrasool@vmware.com> | 2023-06-22 09:56:31 +0200 |
---|---|---|
committer | Mobashshera Rasool <mrasool@vmware.com> | 2023-06-26 16:45:30 +0200 |
commit | 7de521470f0f82db4bd0cfcbe45761b909934639 (patch) | |
tree | b03ca24c2764fcc78b42a90a033be6825dd37ae9 /pimd | |
parent | Merge pull request #13771 from mjstapp/opaque_notify (diff) | |
download | frr-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.c | 25 |
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; |