Lines Matching refs:pmc

83 static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
87 static int sf_setstate(struct ifmcaddr6 *pmc);
88 static void sf_markstate(struct ifmcaddr6 *pmc);
89 static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
118 #define for_each_pmc_rcu(np, pmc) \ argument
119 for (pmc = rcu_dereference(np->ipv6_mc_list); \
120 pmc != NULL; \
121 pmc = rcu_dereference(pmc->next))
315 struct ipv6_mc_socklist *pmc; in ip6_mc_source() local
340 for_each_pmc_rcu(inet6, pmc) { in ip6_mc_source()
341 if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface) in ip6_mc_source()
343 if (ipv6_addr_equal(&pmc->addr, group)) in ip6_mc_source()
346 if (!pmc) { /* must have a prior join */ in ip6_mc_source()
351 if (pmc->sflist) { in ip6_mc_source()
352 if (pmc->sfmode != omode) { in ip6_mc_source()
356 } else if (pmc->sfmode != omode) { in ip6_mc_source()
359 ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0); in ip6_mc_source()
360 pmc->sfmode = omode; in ip6_mc_source()
363 write_lock(&pmc->sflock); in ip6_mc_source()
366 psl = pmc->sflist; in ip6_mc_source()
418 pmc->sflist = psl = newpsl; in ip6_mc_source()
435 write_unlock(&pmc->sflock); in ip6_mc_source()
446 struct ipv6_mc_socklist *pmc; in ip6_mc_msfilter() local
477 for_each_pmc_rcu(inet6, pmc) { in ip6_mc_msfilter()
478 if (pmc->ifindex != gsf->gf_interface) in ip6_mc_msfilter()
480 if (ipv6_addr_equal(&pmc->addr, group)) in ip6_mc_msfilter()
483 if (!pmc) { /* must have a prior join */ in ip6_mc_msfilter()
512 write_lock(&pmc->sflock); in ip6_mc_msfilter()
513 psl = pmc->sflist; in ip6_mc_msfilter()
515 (void) ip6_mc_del_src(idev, group, pmc->sfmode, in ip6_mc_msfilter()
519 (void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0); in ip6_mc_msfilter()
520 pmc->sflist = newpsl; in ip6_mc_msfilter()
521 pmc->sfmode = gsf->gf_fmode; in ip6_mc_msfilter()
522 write_unlock(&pmc->sflock); in ip6_mc_msfilter()
537 struct ipv6_mc_socklist *pmc; in ip6_mc_msfget() local
562 for_each_pmc_rcu(inet6, pmc) { in ip6_mc_msfget()
563 if (pmc->ifindex != gsf->gf_interface) in ip6_mc_msfget()
565 if (ipv6_addr_equal(group, &pmc->addr)) in ip6_mc_msfget()
568 if (!pmc) /* must have a prior join */ in ip6_mc_msfget()
570 gsf->gf_fmode = pmc->sfmode; in ip6_mc_msfget()
571 psl = pmc->sflist; in ip6_mc_msfget()
708 struct ifmcaddr6 *pmc; in mld_add_delrec() local
716 pmc = kzalloc(sizeof(*pmc), GFP_ATOMIC); in mld_add_delrec()
717 if (!pmc) in mld_add_delrec()
721 spin_lock_init(&pmc->mca_lock); in mld_add_delrec()
722 pmc->idev = im->idev; in mld_add_delrec()
724 pmc->mca_addr = im->mca_addr; in mld_add_delrec()
725 pmc->mca_crcount = idev->mc_qrv; in mld_add_delrec()
726 pmc->mca_sfmode = im->mca_sfmode; in mld_add_delrec()
727 if (pmc->mca_sfmode == MCAST_INCLUDE) { in mld_add_delrec()
730 pmc->mca_tomb = im->mca_tomb; in mld_add_delrec()
731 pmc->mca_sources = im->mca_sources; in mld_add_delrec()
733 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) in mld_add_delrec()
734 psf->sf_crcount = pmc->mca_crcount; in mld_add_delrec()
739 pmc->next = idev->mc_tomb; in mld_add_delrec()
740 idev->mc_tomb = pmc; in mld_add_delrec()
746 struct ifmcaddr6 *pmc, *pmc_prev; in mld_del_delrec() local
751 for (pmc = idev->mc_tomb; pmc; pmc = pmc->next) { in mld_del_delrec()
752 if (ipv6_addr_equal(&pmc->mca_addr, pmca)) in mld_del_delrec()
754 pmc_prev = pmc; in mld_del_delrec()
756 if (pmc) { in mld_del_delrec()
758 pmc_prev->next = pmc->next; in mld_del_delrec()
760 idev->mc_tomb = pmc->next; in mld_del_delrec()
764 if (pmc) { in mld_del_delrec()
765 for (psf = pmc->mca_tomb; psf; psf = psf_next) { in mld_del_delrec()
769 in6_dev_put(pmc->idev); in mld_del_delrec()
770 kfree(pmc); in mld_del_delrec()
776 struct ifmcaddr6 *pmc, *nextpmc; in mld_clear_delrec() local
779 pmc = idev->mc_tomb; in mld_clear_delrec()
783 for (; pmc; pmc = nextpmc) { in mld_clear_delrec()
784 nextpmc = pmc->next; in mld_clear_delrec()
785 ip6_mc_clear_src(pmc); in mld_clear_delrec()
786 in6_dev_put(pmc->idev); in mld_clear_delrec()
787 kfree(pmc); in mld_clear_delrec()
792 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in mld_clear_delrec()
795 spin_lock_bh(&pmc->mca_lock); in mld_clear_delrec()
796 psf = pmc->mca_tomb; in mld_clear_delrec()
797 pmc->mca_tomb = NULL; in mld_clear_delrec()
798 spin_unlock_bh(&pmc->mca_lock); in mld_clear_delrec()
1068 static bool mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, in mld_xmarksources() argument
1075 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in mld_xmarksources()
1081 pmc->mca_sfcount[MCAST_EXCLUDE] != in mld_xmarksources()
1090 pmc->mca_flags &= ~MAF_GSQUERY; in mld_xmarksources()
1096 static bool mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, in mld_marksources() argument
1102 if (pmc->mca_sfmode == MCAST_EXCLUDE) in mld_marksources()
1103 return mld_xmarksources(pmc, nsrcs, srcs); in mld_marksources()
1108 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in mld_marksources()
1120 pmc->mca_flags &= ~MAF_GSQUERY; in mld_marksources()
1123 pmc->mca_flags |= MAF_GSQUERY; in mld_marksources()
1468 static bool is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, in is_in() argument
1476 if (!((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp)) { in is_in()
1477 if (pmc->mca_sfmode == MCAST_INCLUDE) in is_in()
1484 return pmc->mca_sfcount[MCAST_EXCLUDE] == in is_in()
1495 if (pmc->mca_sfcount[MCAST_EXCLUDE] == 0 || in is_in()
1498 return pmc->mca_sfcount[MCAST_EXCLUDE] == in is_in()
1503 return (pmc->mca_sfmode == MCAST_INCLUDE) ^ sdeleted; in is_in()
1505 if (pmc->mca_sfmode == MCAST_INCLUDE) in is_in()
1513 mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted) in mld_scount() argument
1518 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in mld_scount()
1519 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) in mld_scount()
1665 static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel) in grec_size() argument
1667 return sizeof(struct mld2_grec) + 16 * mld_scount(pmc,type,gdel,sdel); in grec_size()
1670 static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, in add_grhead() argument
1673 struct net_device *dev = pmc->idev->dev; in add_grhead()
1678 skb = mld_newpack(pmc->idev, dev->mtu); in add_grhead()
1685 pgr->grec_mca = pmc->mca_addr; /* structure copy */ in add_grhead()
1694 static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, in add_grec() argument
1697 struct inet6_dev *idev = pmc->idev; in add_grec()
1704 if (pmc->mca_flags & MAF_NOREPORT) in add_grec()
1714 psf_list = sdeleted ? &pmc->mca_tomb : &pmc->mca_sources; in add_grec()
1724 AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { in add_grec()
1737 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) { in add_grec()
1759 skb = add_grhead(skb, pmc, type, &pgr); in add_grec()
1787 if (pmc->mca_crcount || isquery || crsend) { in add_grec()
1793 skb = add_grhead(skb, pmc, type, &pgr); in add_grec()
1800 pmc->mca_flags &= ~MAF_GSQUERY; /* clear query state */ in add_grec()
1804 static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc) in mld_send_report() argument
1810 if (!pmc) { in mld_send_report()
1811 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in mld_send_report()
1812 if (pmc->mca_flags & MAF_NOREPORT) in mld_send_report()
1814 spin_lock_bh(&pmc->mca_lock); in mld_send_report()
1815 if (pmc->mca_sfcount[MCAST_EXCLUDE]) in mld_send_report()
1819 skb = add_grec(skb, pmc, type, 0, 0, 0); in mld_send_report()
1820 spin_unlock_bh(&pmc->mca_lock); in mld_send_report()
1823 spin_lock_bh(&pmc->mca_lock); in mld_send_report()
1824 if (pmc->mca_sfcount[MCAST_EXCLUDE]) in mld_send_report()
1828 skb = add_grec(skb, pmc, type, 0, 0, 0); in mld_send_report()
1829 spin_unlock_bh(&pmc->mca_lock); in mld_send_report()
1859 struct ifmcaddr6 *pmc, *pmc_prev, *pmc_next; in mld_send_cr() local
1868 for (pmc = idev->mc_tomb; pmc; pmc = pmc_next) { in mld_send_cr()
1869 pmc_next = pmc->next; in mld_send_cr()
1870 if (pmc->mca_sfmode == MCAST_INCLUDE) { in mld_send_cr()
1873 skb = add_grec(skb, pmc, type, 1, 0, 0); in mld_send_cr()
1874 skb = add_grec(skb, pmc, dtype, 1, 1, 0); in mld_send_cr()
1876 if (pmc->mca_crcount) { in mld_send_cr()
1877 if (pmc->mca_sfmode == MCAST_EXCLUDE) { in mld_send_cr()
1879 skb = add_grec(skb, pmc, type, 1, 0, 0); in mld_send_cr()
1881 pmc->mca_crcount--; in mld_send_cr()
1882 if (pmc->mca_crcount == 0) { in mld_send_cr()
1883 mld_clear_zeros(&pmc->mca_tomb); in mld_send_cr()
1884 mld_clear_zeros(&pmc->mca_sources); in mld_send_cr()
1887 if (pmc->mca_crcount == 0 && !pmc->mca_tomb && in mld_send_cr()
1888 !pmc->mca_sources) { in mld_send_cr()
1893 in6_dev_put(pmc->idev); in mld_send_cr()
1894 kfree(pmc); in mld_send_cr()
1896 pmc_prev = pmc; in mld_send_cr()
1901 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in mld_send_cr()
1902 spin_lock_bh(&pmc->mca_lock); in mld_send_cr()
1903 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { in mld_send_cr()
1910 skb = add_grec(skb, pmc, type, 0, 0, 0); in mld_send_cr()
1911 skb = add_grec(skb, pmc, dtype, 0, 1, 0); /* deleted sources */ in mld_send_cr()
1914 if (pmc->mca_crcount) { in mld_send_cr()
1915 if (pmc->mca_sfmode == MCAST_EXCLUDE) in mld_send_cr()
1919 skb = add_grec(skb, pmc, type, 0, 0, 0); in mld_send_cr()
1920 pmc->mca_crcount--; in mld_send_cr()
1922 spin_unlock_bh(&pmc->mca_lock); in mld_send_cr()
2030 struct ifmcaddr6 *pmc; in mld_send_initial_cr() local
2038 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in mld_send_initial_cr()
2039 spin_lock_bh(&pmc->mca_lock); in mld_send_initial_cr()
2040 if (pmc->mca_sfcount[MCAST_EXCLUDE]) in mld_send_initial_cr()
2044 skb = add_grec(skb, pmc, type, 0, 0, 1); in mld_send_initial_cr()
2045 spin_unlock_bh(&pmc->mca_lock); in mld_send_initial_cr()
2076 static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, in ip6_mc_del1_src() argument
2083 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in ip6_mc_del1_src()
2094 struct inet6_dev *idev = pmc->idev; in ip6_mc_del1_src()
2100 pmc->mca_sources = psf->sf_next; in ip6_mc_del1_src()
2101 if (psf->sf_oldin && !(pmc->mca_flags & MAF_NOREPORT) && in ip6_mc_del1_src()
2104 psf->sf_next = pmc->mca_tomb; in ip6_mc_del1_src()
2105 pmc->mca_tomb = psf; in ip6_mc_del1_src()
2117 struct ifmcaddr6 *pmc; in ip6_mc_del_src() local
2124 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in ip6_mc_del_src()
2125 if (ipv6_addr_equal(pmca, &pmc->mca_addr)) in ip6_mc_del_src()
2128 if (!pmc) { in ip6_mc_del_src()
2133 spin_lock_bh(&pmc->mca_lock); in ip6_mc_del_src()
2134 sf_markstate(pmc); in ip6_mc_del_src()
2136 if (!pmc->mca_sfcount[sfmode]) { in ip6_mc_del_src()
2137 spin_unlock_bh(&pmc->mca_lock); in ip6_mc_del_src()
2141 pmc->mca_sfcount[sfmode]--; in ip6_mc_del_src()
2145 int rv = ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]); in ip6_mc_del_src()
2151 if (pmc->mca_sfmode == MCAST_EXCLUDE && in ip6_mc_del_src()
2152 pmc->mca_sfcount[MCAST_EXCLUDE] == 0 && in ip6_mc_del_src()
2153 pmc->mca_sfcount[MCAST_INCLUDE]) { in ip6_mc_del_src()
2157 pmc->mca_sfmode = MCAST_INCLUDE; in ip6_mc_del_src()
2158 pmc->mca_crcount = idev->mc_qrv; in ip6_mc_del_src()
2159 idev->mc_ifc_count = pmc->mca_crcount; in ip6_mc_del_src()
2160 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) in ip6_mc_del_src()
2162 mld_ifc_event(pmc->idev); in ip6_mc_del_src()
2163 } else if (sf_setstate(pmc) || changerec) in ip6_mc_del_src()
2164 mld_ifc_event(pmc->idev); in ip6_mc_del_src()
2165 spin_unlock_bh(&pmc->mca_lock); in ip6_mc_del_src()
2173 static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode, in ip6_mc_add1_src() argument
2179 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in ip6_mc_add1_src()
2193 pmc->mca_sources = psf; in ip6_mc_add1_src()
2199 static void sf_markstate(struct ifmcaddr6 *pmc) in sf_markstate() argument
2202 int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE]; in sf_markstate()
2204 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) in sf_markstate()
2205 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { in sf_markstate()
2213 static int sf_setstate(struct ifmcaddr6 *pmc) in sf_setstate() argument
2216 int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE]; in sf_setstate()
2217 int qrv = pmc->idev->mc_qrv; in sf_setstate()
2221 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in sf_setstate()
2222 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { in sf_setstate()
2231 for (dpsf = pmc->mca_tomb; dpsf; in sf_setstate()
2242 pmc->mca_tomb = dpsf->sf_next; in sf_setstate()
2254 for (dpsf = pmc->mca_tomb; dpsf; dpsf = dpsf->sf_next) in sf_setstate()
2264 dpsf->sf_next = pmc->mca_tomb; in sf_setstate()
2265 pmc->mca_tomb = dpsf; in sf_setstate()
2281 struct ifmcaddr6 *pmc; in ip6_mc_add_src() local
2288 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in ip6_mc_add_src()
2289 if (ipv6_addr_equal(pmca, &pmc->mca_addr)) in ip6_mc_add_src()
2292 if (!pmc) { in ip6_mc_add_src()
2297 spin_lock_bh(&pmc->mca_lock); in ip6_mc_add_src()
2299 sf_markstate(pmc); in ip6_mc_add_src()
2300 isexclude = pmc->mca_sfmode == MCAST_EXCLUDE; in ip6_mc_add_src()
2302 pmc->mca_sfcount[sfmode]++; in ip6_mc_add_src()
2305 err = ip6_mc_add1_src(pmc, sfmode, &psfsrc[i]); in ip6_mc_add_src()
2313 pmc->mca_sfcount[sfmode]--; in ip6_mc_add_src()
2315 ip6_mc_del1_src(pmc, sfmode, &psfsrc[j]); in ip6_mc_add_src()
2316 } else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) { in ip6_mc_add_src()
2320 if (pmc->mca_sfcount[MCAST_EXCLUDE]) in ip6_mc_add_src()
2321 pmc->mca_sfmode = MCAST_EXCLUDE; in ip6_mc_add_src()
2322 else if (pmc->mca_sfcount[MCAST_INCLUDE]) in ip6_mc_add_src()
2323 pmc->mca_sfmode = MCAST_INCLUDE; in ip6_mc_add_src()
2326 pmc->mca_crcount = idev->mc_qrv; in ip6_mc_add_src()
2327 idev->mc_ifc_count = pmc->mca_crcount; in ip6_mc_add_src()
2328 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) in ip6_mc_add_src()
2331 } else if (sf_setstate(pmc)) in ip6_mc_add_src()
2333 spin_unlock_bh(&pmc->mca_lock); in ip6_mc_add_src()
2338 static void ip6_mc_clear_src(struct ifmcaddr6 *pmc) in ip6_mc_clear_src() argument
2342 for (psf = pmc->mca_tomb; psf; psf = nextpsf) { in ip6_mc_clear_src()
2346 pmc->mca_tomb = NULL; in ip6_mc_clear_src()
2347 for (psf = pmc->mca_sources; psf; psf = nextpsf) { in ip6_mc_clear_src()
2351 pmc->mca_sources = NULL; in ip6_mc_clear_src()
2352 pmc->mca_sfmode = MCAST_EXCLUDE; in ip6_mc_clear_src()
2353 pmc->mca_sfcount[MCAST_INCLUDE] = 0; in ip6_mc_clear_src()
2354 pmc->mca_sfcount[MCAST_EXCLUDE] = 1; in ip6_mc_clear_src()