static int sf_setstate(struct ifmcaddr6 *pmc)
{
	struct ip6_sf_list *psf, *dpsf;
	int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE];
	int qrv = pmc->idev->mc_qrv;
	int new_in, rv;

	rv = 0;
	for_each_psf_mclock(pmc, psf) {
		if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
			new_in = mca_xcount == psf->sf_count[MCAST_EXCLUDE] &&
				!psf->sf_count[MCAST_INCLUDE];
		} else
			new_in = psf->sf_count[MCAST_INCLUDE] != 0;
		if (new_in) {
			if (!psf->sf_oldin) {
				struct ip6_sf_list *prev = NULL;

				for_each_psf_tomb(pmc, dpsf) {
					if (ipv6_addr_equal(&dpsf->sf_addr,
					    &psf->sf_addr))
						break;
					prev = dpsf;
				}
				if (dpsf) {
					if (prev)
						rcu_assign_pointer(prev->sf_next,
								   mc_dereference(dpsf->sf_next,
										  pmc->idev));
					else
						rcu_assign_pointer(pmc->mca_tomb,
								   mc_dereference(dpsf->sf_next,
										  pmc->idev));
					kfree_rcu(dpsf, rcu);
				}
				psf->sf_crcount = qrv;
				rv++;
			}
		} else if (psf->sf_oldin) {
			psf->sf_crcount = 0;
			/*
			 * add or update "delete" records if an active filter
			 * is now inactive
			 */

			for_each_psf_tomb(pmc, dpsf)
				if (ipv6_addr_equal(&dpsf->sf_addr,
				    &psf->sf_addr))
					break;
			if (!dpsf) {
				dpsf = kmalloc(sizeof(*dpsf), GFP_KERNEL);
				if (!dpsf)
					continue;
				*dpsf = *psf;
				rcu_assign_pointer(dpsf->sf_next,
						   mc_dereference(pmc->mca_tomb, pmc->idev));
				rcu_assign_pointer(pmc->mca_tomb, dpsf);
			}
			dpsf->sf_crcount = qrv;
			rv++;
		}
	}
	return rv;
}
static int sf_setstate(struct ifmcaddr6 *pmc)
{
	struct ip6_sf_list *psf, *dpsf;
	int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE];
	int qrv = pmc->idev->mc_qrv;
	int new_in, rv;

	rv = 0;
	for_each_psf_mclock(pmc, psf) {
		if (pmc->mca_sfcount[MCAST_EXCLUDE]) {
			new_in = mca_xcount == psf->sf_count[MCAST_EXCLUDE] &&
				!psf->sf_count[MCAST_INCLUDE];
		} else
			new_in = psf->sf_count[MCAST_INCLUDE] != 0;
		if (new_in) {
			if (!psf->sf_oldin) {
				struct ip6_sf_list *prev = NULL;

				for_each_psf_tomb(pmc, dpsf) {
					if (ipv6_addr_equal(&dpsf->sf_addr,
					    &psf->sf_addr))
						break;
					prev = dpsf;
				}
				if (dpsf) {
					if (prev)
						rcu_assign_pointer(prev->sf_next,
								   mc_dereference(dpsf->sf_next,
										  pmc->idev));
					else
						rcu_assign_pointer(pmc->mca_tomb,
								   mc_dereference(dpsf->sf_next,
										  pmc->idev));
					kfree_rcu(dpsf, rcu);
				}
				psf->sf_crcount = qrv;
				rv++;
			}
		} else if (psf->sf_oldin) {
			psf->sf_crcount = 0;
			 

			for_each_psf_tomb(pmc, dpsf)
				if (ipv6_addr_equal(&dpsf->sf_addr,
				    &psf->sf_addr))
					break;
			if (!dpsf) {
				dpsf = kmalloc(sizeof(*dpsf), GFP_KERNEL);
				if (!dpsf)
					continue;
				*dpsf = *psf;
				rcu_assign_pointer(dpsf->sf_next,
						   mc_dereference(pmc->mca_tomb, pmc->idev));
				rcu_assign_pointer(pmc->mca_tomb, dpsf);
			}
			dpsf->sf_crcount = qrv;
			rv++;
		}
	}
	return rv;
}