static void mld_send_cr(struct inet6_dev *idev)
{
	struct ifmcaddr6 *pmc, *pmc_prev, *pmc_next;
	struct sk_buff *skb = NULL;
	int type, dtype;

	/* deleted MCA's */
	pmc_prev = NULL;
	for (pmc = mc_dereference(idev->mc_tomb, idev);
	     pmc;
	     pmc = pmc_next) {
		pmc_next = mc_dereference(pmc->next, idev);
		if (pmc->mca_sfmode == MCAST_INCLUDE) {
			type = MLD2_BLOCK_OLD_SOURCES;
			dtype = MLD2_BLOCK_OLD_SOURCES;
			skb = add_grec(skb, pmc, type, 1, 0, 0);
			skb = add_grec(skb, pmc, dtype, 1, 1, 0);
		}
		if (pmc->mca_crcount) {
			if (pmc->mca_sfmode == MCAST_EXCLUDE) {
				type = MLD2_CHANGE_TO_INCLUDE;
				skb = add_grec(skb, pmc, type, 1, 0, 0);
			}
			pmc->mca_crcount--;
			if (pmc->mca_crcount == 0) {
				mld_clear_zeros(&pmc->mca_tomb, idev);
				mld_clear_zeros(&pmc->mca_sources, idev);
			}
		}
		if (pmc->mca_crcount == 0 &&
		    !rcu_access_pointer(pmc->mca_tomb) &&
		    !rcu_access_pointer(pmc->mca_sources)) {
			if (pmc_prev)
				rcu_assign_pointer(pmc_prev->next, pmc_next);
			else
				rcu_assign_pointer(idev->mc_tomb, pmc_next);
			in6_dev_put(pmc->idev);
			kfree_rcu(pmc, rcu);
		} else
			pmc_prev = pmc;
	}

	/* change recs */
	for_each_mc_mclock(idev, pmc) {
		if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
			type = MLD2_BLOCK_OLD_SOURCES;
			dtype = MLD2_ALLOW_NEW_SOURCES;
		} else {
			type = MLD2_ALLOW_NEW_SOURCES;
			dtype = MLD2_BLOCK_OLD_SOURCES;
		}
		skb = add_grec(skb, pmc, type, 0, 0, 0);
		skb = add_grec(skb, pmc, dtype, 0, 1, 0);	/* deleted sources */

		/* filter mode changes */
		if (pmc->mca_crcount) {
			if (pmc->mca_sfmode == MCAST_EXCLUDE)
				type = MLD2_CHANGE_TO_EXCLUDE;
			else
				type = MLD2_CHANGE_TO_INCLUDE;
			skb = add_grec(skb, pmc, type, 0, 0, 0);
			pmc->mca_crcount--;
		}
	}
	if (!skb)
		return;
	(void) mld_sendpack(skb);
}
static void mld_send_cr(struct inet6_dev *idev)
{
	struct ifmcaddr6 *pmc, *pmc_prev, *pmc_next;
	struct sk_buff *skb = NULL;
	int type, dtype;

	 
	pmc_prev = NULL;
	for (pmc = mc_dereference(idev->mc_tomb, idev);
	     pmc;
	     pmc = pmc_next) {
		pmc_next = mc_dereference(pmc->next, idev);
		if (pmc->mca_sfmode == MCAST_INCLUDE) {
			type = MLD2_BLOCK_OLD_SOURCES;
			dtype = MLD2_BLOCK_OLD_SOURCES;
			skb = add_grec(skb, pmc, type, 1, 0, 0);
			skb = add_grec(skb, pmc, dtype, 1, 1, 0);
		}
		if (pmc->mca_crcount) {
			if (pmc->mca_sfmode == MCAST_EXCLUDE) {
				type = MLD2_CHANGE_TO_INCLUDE;
				skb = add_grec(skb, pmc, type, 1, 0, 0);
			}
			pmc->mca_crcount--;
			if (pmc->mca_crcount == 0) {
				mld_clear_zeros(&pmc->mca_tomb, idev);
				mld_clear_zeros(&pmc->mca_sources, idev);
			}
		}
		if (pmc->mca_crcount == 0 &&
		    !rcu_access_pointer(pmc->mca_tomb) &&
		    !rcu_access_pointer(pmc->mca_sources)) {
			if (pmc_prev)
				rcu_assign_pointer(pmc_prev->next, pmc_next);
			else
				rcu_assign_pointer(idev->mc_tomb, pmc_next);
			in6_dev_put(pmc->idev);
			kfree_rcu(pmc, rcu);
		} else
			pmc_prev = pmc;
	}

	 
	for_each_mc_mclock(idev, pmc) {
		if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
			type = MLD2_BLOCK_OLD_SOURCES;
			dtype = MLD2_ALLOW_NEW_SOURCES;
		} else {
			type = MLD2_ALLOW_NEW_SOURCES;
			dtype = MLD2_BLOCK_OLD_SOURCES;
		}
		skb = add_grec(skb, pmc, type, 0, 0, 0);
		skb = add_grec(skb, pmc, dtype, 0, 1, 0);	 

		 
		if (pmc->mca_crcount) {
			if (pmc->mca_sfmode == MCAST_EXCLUDE)
				type = MLD2_CHANGE_TO_EXCLUDE;
			else
				type = MLD2_CHANGE_TO_INCLUDE;
			skb = add_grec(skb, pmc, type, 0, 0, 0);
			pmc->mca_crcount--;
		}
	}
	if (!skb)
		return;
	(void) mld_sendpack(skb);
}