FreeBSD/sys/netinet6/mld6.c
/*
 * Update the report timer on a group in response to an MLDv1 query.
 *
 * If we are becoming the reporting member for this group, start the timer.
 * If we already are the reporting member for this group, and timer is
 * below the threshold, reset it.
 *
 * We may be updating the group for the first time since we switched
 * to MLDv2. If we are, then we must clear any recorded source lists,
 * and transition to REPORTING state; the group timer is overloaded
 * for group and group-source query responses. 
 *
 * Unlike MLDv2, the delay per group should be jittered
 * to avoid bursts of MLDv1 reports.
 */
Update the report timer on a group in response to an MLDv1 query.
If we are becoming the reporting member for this group, start the timer.
If we already are the reporting member for this group, and timer is
below the threshold, reset it.

We may be updating the group for the first time since we switched
to MLDv2. If we are, then we must clear any recorded source lists,
and transition to REPORTING state; the group timer is overloaded
for group and group-source query responses.

Unlike MLDv2, the delay per group should be jittered
to avoid bursts of MLDv1 reports.
Update the report timer on a group in response to an MLDv1 query . If we are becoming the reporting member for this group start the timer . If we already are the reporting member for this group and timer is below the threshold reset it . We may be updating the group for the first time since we switched to MLDv2 . If we are then we must clear any recorded source lists and transition to REPORTING state ; the group timer is overloaded for group and group - source query responses . Unlike MLDv2 the delay per group should be jittered to avoid bursts of MLDv1 reports .
static void
mld_v1_update_group(struct in6_multi *inm, const int timer)
{
#ifdef KTR
	char			 ip6tbuf[INET6_ADDRSTRLEN];
#endif
	CTR4(KTR_MLD, "%s: %s/%s timer=%d", __func__,
	    ip6_sprintf(ip6tbuf, &inm->in6m_addr),
	    if_name(inm->in6m_ifp), timer);
	IN6_MULTI_LOCK_ASSERT();
	switch (inm->in6m_state) {
	case MLD_NOT_MEMBER:
	case MLD_SILENT_MEMBER:
		break;
	case MLD_REPORTING_MEMBER:
		if (inm->in6m_timer != 0 &&
		    inm->in6m_timer <= timer) {
			CTR1(KTR_MLD, "%s: REPORTING and timer running, "
			    "skipping.", __func__);
			break;
		}
	case MLD_SG_QUERY_PENDING_MEMBER:
	case MLD_G_QUERY_PENDING_MEMBER:
	case MLD_IDLE_MEMBER:
	case MLD_LAZY_MEMBER:
	case MLD_AWAKENING_MEMBER:
		CTR1(KTR_MLD, "%s: ->REPORTING", __func__);
		inm->in6m_state = MLD_REPORTING_MEMBER;
		inm->in6m_timer = MLD_RANDOM_DELAY(timer);
		V_current_state_timers_running6 = 1;
		break;
	case MLD_SLEEPING_MEMBER:
		CTR1(KTR_MLD, "%s: ->AWAKENING", __func__);
		inm->in6m_state = MLD_AWAKENING_MEMBER;
		break;
	case MLD_LEAVING_MEMBER:
		break;
	}
}
static void mld_v1_update_group ( struct in6_multi * inm , const int timer ) { #ifdef KTR char ip6tbuf [ INET6_ADDRSTRLEN ] ; #endif CTR4 ( KTR_MLD , " " , __func__ , ip6_sprintf ( ip6tbuf , & inm -> in6m_addr ) , if_name ( inm -> in6m_ifp ) , timer ) ; IN6_MULTI_LOCK_ASSERT ( ) ; switch ( inm -> in6m_state ) { case MLD_NOT_MEMBER : case MLD_SILENT_MEMBER : break ; case MLD_REPORTING_MEMBER : if ( inm -> in6m_timer != 0 && inm -> in6m_timer <= timer ) { CTR1 ( KTR_MLD , " " " " , __func__ ) ; break ; } case MLD_SG_QUERY_PENDING_MEMBER : case MLD_G_QUERY_PENDING_MEMBER : case MLD_IDLE_MEMBER : case MLD_LAZY_MEMBER : case MLD_AWAKENING_MEMBER : CTR1 ( KTR_MLD , " " , __func__ ) ; inm -> in6m_state = MLD_REPORTING_MEMBER ; inm -> in6m_timer = MLD_RANDOM_DELAY ( timer ) ; V_current_state_timers_running6 = 1 ; break ; case MLD_SLEEPING_MEMBER : CTR1 ( KTR_MLD , " " , __func__ ) ; inm -> in6m_state = MLD_AWAKENING_MEMBER ; break ; case MLD_LEAVING_MEMBER : break ; } }
Update the report timer on a group in response to an MLDv1 query.
Update the report timer on a group in response to an MLDv1 query .
/* FALLTHROUGH */