Lines Matching full:pmc

79 static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
80 static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc);
83 static int sf_setstate(struct ifmcaddr6 *pmc);
84 static void sf_markstate(struct ifmcaddr6 *pmc);
85 static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
116 #define for_each_pmc_rcu(np, pmc) \ argument
117 for (pmc = rcu_dereference(np->ipv6_mc_list); \
118 pmc != NULL; \
119 pmc = rcu_dereference(pmc->next))
332 struct ipv6_mc_socklist *pmc; in ip6_mc_source() local
357 for_each_pmc_rcu(inet6, pmc) { in ip6_mc_source()
358 if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface) in ip6_mc_source()
360 if (ipv6_addr_equal(&pmc->addr, group)) in ip6_mc_source()
363 if (!pmc) { /* must have a prior join */ in ip6_mc_source()
368 if (pmc->sflist) { in ip6_mc_source()
369 if (pmc->sfmode != omode) { in ip6_mc_source()
373 } else if (pmc->sfmode != omode) { in ip6_mc_source()
376 ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0); in ip6_mc_source()
377 pmc->sfmode = omode; in ip6_mc_source()
380 write_lock(&pmc->sflock); in ip6_mc_source()
383 psl = pmc->sflist; in ip6_mc_source()
435 pmc->sflist = psl = newpsl; in ip6_mc_source()
452 write_unlock(&pmc->sflock); in ip6_mc_source()
464 struct ipv6_mc_socklist *pmc; in ip6_mc_msfilter() local
495 for_each_pmc_rcu(inet6, pmc) { in ip6_mc_msfilter()
496 if (pmc->ifindex != gsf->gf_interface) in ip6_mc_msfilter()
498 if (ipv6_addr_equal(&pmc->addr, group)) in ip6_mc_msfilter()
501 if (!pmc) { /* must have a prior join */ in ip6_mc_msfilter()
530 write_lock(&pmc->sflock); in ip6_mc_msfilter()
531 psl = pmc->sflist; in ip6_mc_msfilter()
533 (void) ip6_mc_del_src(idev, group, pmc->sfmode, in ip6_mc_msfilter()
537 (void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0); in ip6_mc_msfilter()
538 pmc->sflist = newpsl; in ip6_mc_msfilter()
539 pmc->sfmode = gsf->gf_fmode; in ip6_mc_msfilter()
540 write_unlock(&pmc->sflock); in ip6_mc_msfilter()
555 struct ipv6_mc_socklist *pmc; in ip6_mc_msfget() local
580 for_each_pmc_rcu(inet6, pmc) { in ip6_mc_msfget()
581 if (pmc->ifindex != gsf->gf_interface) in ip6_mc_msfget()
583 if (ipv6_addr_equal(group, &pmc->addr)) in ip6_mc_msfget()
586 if (!pmc) /* must have a prior join */ in ip6_mc_msfget()
588 gsf->gf_fmode = pmc->sfmode; in ip6_mc_msfget()
589 psl = pmc->sflist; in ip6_mc_msfget()
597 * on pmc->sflock. We have the socket lock so reading here is safe. in ip6_mc_msfget()
726 struct ifmcaddr6 *pmc; in mld_add_delrec() local
734 pmc = kzalloc(sizeof(*pmc), GFP_ATOMIC); in mld_add_delrec()
735 if (!pmc) in mld_add_delrec()
739 spin_lock_init(&pmc->mca_lock); in mld_add_delrec()
740 pmc->idev = im->idev; in mld_add_delrec()
742 pmc->mca_addr = im->mca_addr; in mld_add_delrec()
743 pmc->mca_crcount = idev->mc_qrv; in mld_add_delrec()
744 pmc->mca_sfmode = im->mca_sfmode; in mld_add_delrec()
745 if (pmc->mca_sfmode == MCAST_INCLUDE) { in mld_add_delrec()
748 pmc->mca_tomb = im->mca_tomb; in mld_add_delrec()
749 pmc->mca_sources = im->mca_sources; in mld_add_delrec()
751 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) in mld_add_delrec()
752 psf->sf_crcount = pmc->mca_crcount; in mld_add_delrec()
757 pmc->next = idev->mc_tomb; in mld_add_delrec()
758 idev->mc_tomb = pmc; in mld_add_delrec()
764 struct ifmcaddr6 *pmc, *pmc_prev; in mld_del_delrec() local
770 for (pmc = idev->mc_tomb; pmc; pmc = pmc->next) { in mld_del_delrec()
771 if (ipv6_addr_equal(&pmc->mca_addr, pmca)) in mld_del_delrec()
773 pmc_prev = pmc; in mld_del_delrec()
775 if (pmc) { in mld_del_delrec()
777 pmc_prev->next = pmc->next; in mld_del_delrec()
779 idev->mc_tomb = pmc->next; in mld_del_delrec()
784 if (pmc) { in mld_del_delrec()
785 im->idev = pmc->idev; in mld_del_delrec()
787 swap(im->mca_tomb, pmc->mca_tomb); in mld_del_delrec()
788 swap(im->mca_sources, pmc->mca_sources); in mld_del_delrec()
794 in6_dev_put(pmc->idev); in mld_del_delrec()
795 ip6_mc_clear_src(pmc); in mld_del_delrec()
796 kfree(pmc); in mld_del_delrec()
803 struct ifmcaddr6 *pmc, *nextpmc; in mld_clear_delrec() local
806 pmc = idev->mc_tomb; in mld_clear_delrec()
810 for (; pmc; pmc = nextpmc) { in mld_clear_delrec()
811 nextpmc = pmc->next; in mld_clear_delrec()
812 ip6_mc_clear_src(pmc); in mld_clear_delrec()
813 in6_dev_put(pmc->idev); in mld_clear_delrec()
814 kfree(pmc); in mld_clear_delrec()
819 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in mld_clear_delrec()
822 spin_lock_bh(&pmc->mca_lock); in mld_clear_delrec()
823 psf = pmc->mca_tomb; in mld_clear_delrec()
824 pmc->mca_tomb = NULL; in mld_clear_delrec()
825 spin_unlock_bh(&pmc->mca_lock); in mld_clear_delrec()
1103 static bool mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, in mld_xmarksources() argument
1110 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in mld_xmarksources()
1116 pmc->mca_sfcount[MCAST_EXCLUDE] != in mld_xmarksources()
1125 pmc->mca_flags &= ~MAF_GSQUERY; in mld_xmarksources()
1131 static bool mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, in mld_marksources() argument
1137 if (pmc->mca_sfmode == MCAST_EXCLUDE) in mld_marksources()
1138 return mld_xmarksources(pmc, nsrcs, srcs); in mld_marksources()
1143 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in mld_marksources()
1155 pmc->mca_flags &= ~MAF_GSQUERY; in mld_marksources()
1158 pmc->mca_flags |= MAF_GSQUERY; in mld_marksources()
1503 static bool is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, in is_in() argument
1511 if (!((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp)) { in is_in()
1512 if (pmc->mca_sfmode == MCAST_INCLUDE) in is_in()
1519 return pmc->mca_sfcount[MCAST_EXCLUDE] == in is_in()
1530 if (pmc->mca_sfcount[MCAST_EXCLUDE] == 0 || in is_in()
1533 return pmc->mca_sfcount[MCAST_EXCLUDE] == in is_in()
1538 return (pmc->mca_sfmode == MCAST_INCLUDE) ^ sdeleted; in is_in()
1540 if (pmc->mca_sfmode == MCAST_INCLUDE) in is_in()
1548 mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted) in mld_scount() argument
1553 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in mld_scount()
1554 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) in mld_scount()
1698 static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel) in grec_size() argument
1700 return sizeof(struct mld2_grec) + 16 * mld_scount(pmc,type,gdel,sdel); in grec_size()
1703 static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, in add_grhead() argument
1710 skb = mld_newpack(pmc->idev, mtu); in add_grhead()
1718 pgr->grec_mca = pmc->mca_addr; /* structure copy */ in add_grhead()
1727 static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, in add_grec() argument
1730 struct inet6_dev *idev = pmc->idev; in add_grec()
1738 if (pmc->mca_flags & MAF_NOREPORT) in add_grec()
1752 psf_list = sdeleted ? &pmc->mca_tomb : &pmc->mca_sources; in add_grec()
1762 AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { in add_grec()
1775 if (!is_in(pmc, psf, type, gdeleted, sdeleted) && !crsend) { in add_grec()
1783 if (((gdeleted && pmc->mca_sfmode == MCAST_EXCLUDE) || in add_grec()
1784 (!gdeleted && pmc->mca_crcount)) && in add_grec()
1806 skb = add_grhead(skb, pmc, type, &pgr, mtu); in add_grec()
1835 if (pmc->mca_crcount || isquery || crsend) { in add_grec()
1841 skb = add_grhead(skb, pmc, type, &pgr, mtu); in add_grec()
1848 pmc->mca_flags &= ~MAF_GSQUERY; /* clear query state */ in add_grec()
1852 static void mld_send_report(struct inet6_dev *idev, struct ifmcaddr6 *pmc) in mld_send_report() argument
1858 if (!pmc) { in mld_send_report()
1859 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in mld_send_report()
1860 if (pmc->mca_flags & MAF_NOREPORT) in mld_send_report()
1862 spin_lock_bh(&pmc->mca_lock); in mld_send_report()
1863 if (pmc->mca_sfcount[MCAST_EXCLUDE]) in mld_send_report()
1867 skb = add_grec(skb, pmc, type, 0, 0, 0); in mld_send_report()
1868 spin_unlock_bh(&pmc->mca_lock); in mld_send_report()
1871 spin_lock_bh(&pmc->mca_lock); in mld_send_report()
1872 if (pmc->mca_sfcount[MCAST_EXCLUDE]) in mld_send_report()
1876 skb = add_grec(skb, pmc, type, 0, 0, 0); in mld_send_report()
1877 spin_unlock_bh(&pmc->mca_lock); in mld_send_report()
1907 struct ifmcaddr6 *pmc, *pmc_prev, *pmc_next; in mld_send_cr() local
1916 for (pmc = idev->mc_tomb; pmc; pmc = pmc_next) { in mld_send_cr()
1917 pmc_next = pmc->next; in mld_send_cr()
1918 if (pmc->mca_sfmode == MCAST_INCLUDE) { in mld_send_cr()
1921 skb = add_grec(skb, pmc, type, 1, 0, 0); in mld_send_cr()
1922 skb = add_grec(skb, pmc, dtype, 1, 1, 0); in mld_send_cr()
1924 if (pmc->mca_crcount) { in mld_send_cr()
1925 if (pmc->mca_sfmode == MCAST_EXCLUDE) { in mld_send_cr()
1927 skb = add_grec(skb, pmc, type, 1, 0, 0); in mld_send_cr()
1929 pmc->mca_crcount--; in mld_send_cr()
1930 if (pmc->mca_crcount == 0) { in mld_send_cr()
1931 mld_clear_zeros(&pmc->mca_tomb); in mld_send_cr()
1932 mld_clear_zeros(&pmc->mca_sources); in mld_send_cr()
1935 if (pmc->mca_crcount == 0 && !pmc->mca_tomb && in mld_send_cr()
1936 !pmc->mca_sources) { in mld_send_cr()
1941 in6_dev_put(pmc->idev); in mld_send_cr()
1942 kfree(pmc); in mld_send_cr()
1944 pmc_prev = pmc; in mld_send_cr()
1949 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in mld_send_cr()
1950 spin_lock_bh(&pmc->mca_lock); in mld_send_cr()
1951 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { in mld_send_cr()
1958 skb = add_grec(skb, pmc, type, 0, 0, 0); in mld_send_cr()
1959 skb = add_grec(skb, pmc, dtype, 0, 1, 0); /* deleted sources */ in mld_send_cr()
1962 if (pmc->mca_crcount) { in mld_send_cr()
1963 if (pmc->mca_sfmode == MCAST_EXCLUDE) in mld_send_cr()
1967 skb = add_grec(skb, pmc, type, 0, 0, 0); in mld_send_cr()
1968 pmc->mca_crcount--; in mld_send_cr()
1970 spin_unlock_bh(&pmc->mca_lock); in mld_send_cr()
2077 struct ifmcaddr6 *pmc; in mld_send_initial_cr() local
2085 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in mld_send_initial_cr()
2086 spin_lock_bh(&pmc->mca_lock); in mld_send_initial_cr()
2087 if (pmc->mca_sfcount[MCAST_EXCLUDE]) in mld_send_initial_cr()
2091 skb = add_grec(skb, pmc, type, 0, 0, 1); in mld_send_initial_cr()
2092 spin_unlock_bh(&pmc->mca_lock); in mld_send_initial_cr()
2125 static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, in ip6_mc_del1_src() argument
2132 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in ip6_mc_del1_src()
2143 struct inet6_dev *idev = pmc->idev; in ip6_mc_del1_src()
2149 pmc->mca_sources = psf->sf_next; in ip6_mc_del1_src()
2150 if (psf->sf_oldin && !(pmc->mca_flags & MAF_NOREPORT) && in ip6_mc_del1_src()
2153 psf->sf_next = pmc->mca_tomb; in ip6_mc_del1_src()
2154 pmc->mca_tomb = psf; in ip6_mc_del1_src()
2166 struct ifmcaddr6 *pmc; in ip6_mc_del_src() local
2173 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in ip6_mc_del_src()
2174 if (ipv6_addr_equal(pmca, &pmc->mca_addr)) in ip6_mc_del_src()
2177 if (!pmc) { in ip6_mc_del_src()
2182 spin_lock_bh(&pmc->mca_lock); in ip6_mc_del_src()
2183 sf_markstate(pmc); in ip6_mc_del_src()
2185 if (!pmc->mca_sfcount[sfmode]) { in ip6_mc_del_src()
2186 spin_unlock_bh(&pmc->mca_lock); in ip6_mc_del_src()
2190 pmc->mca_sfcount[sfmode]--; in ip6_mc_del_src()
2194 int rv = ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]); in ip6_mc_del_src()
2200 if (pmc->mca_sfmode == MCAST_EXCLUDE && in ip6_mc_del_src()
2201 pmc->mca_sfcount[MCAST_EXCLUDE] == 0 && in ip6_mc_del_src()
2202 pmc->mca_sfcount[MCAST_INCLUDE]) { in ip6_mc_del_src()
2206 pmc->mca_sfmode = MCAST_INCLUDE; in ip6_mc_del_src()
2207 pmc->mca_crcount = idev->mc_qrv; in ip6_mc_del_src()
2208 idev->mc_ifc_count = pmc->mca_crcount; in ip6_mc_del_src()
2209 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) in ip6_mc_del_src()
2211 mld_ifc_event(pmc->idev); in ip6_mc_del_src()
2212 } else if (sf_setstate(pmc) || changerec) in ip6_mc_del_src()
2213 mld_ifc_event(pmc->idev); in ip6_mc_del_src()
2214 spin_unlock_bh(&pmc->mca_lock); in ip6_mc_del_src()
2222 static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode, in ip6_mc_add1_src() argument
2228 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in ip6_mc_add1_src()
2242 pmc->mca_sources = psf; in ip6_mc_add1_src()
2248 static void sf_markstate(struct ifmcaddr6 *pmc) in sf_markstate() argument
2251 int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE]; in sf_markstate()
2253 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) in sf_markstate()
2254 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { in sf_markstate()
2262 static int sf_setstate(struct ifmcaddr6 *pmc) in sf_setstate() argument
2265 int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE]; in sf_setstate()
2266 int qrv = pmc->idev->mc_qrv; in sf_setstate()
2270 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) { in sf_setstate()
2271 if (pmc->mca_sfcount[MCAST_EXCLUDE]) { in sf_setstate()
2280 for (dpsf = pmc->mca_tomb; dpsf; in sf_setstate()
2291 pmc->mca_tomb = dpsf->sf_next; in sf_setstate()
2303 for (dpsf = pmc->mca_tomb; dpsf; dpsf = dpsf->sf_next) in sf_setstate()
2312 /* pmc->mca_lock held by callers */ in sf_setstate()
2313 dpsf->sf_next = pmc->mca_tomb; in sf_setstate()
2314 pmc->mca_tomb = dpsf; in sf_setstate()
2330 struct ifmcaddr6 *pmc; in ip6_mc_add_src() local
2337 for (pmc = idev->mc_list; pmc; pmc = pmc->next) { in ip6_mc_add_src()
2338 if (ipv6_addr_equal(pmca, &pmc->mca_addr)) in ip6_mc_add_src()
2341 if (!pmc) { in ip6_mc_add_src()
2346 spin_lock_bh(&pmc->mca_lock); in ip6_mc_add_src()
2348 sf_markstate(pmc); in ip6_mc_add_src()
2349 isexclude = pmc->mca_sfmode == MCAST_EXCLUDE; in ip6_mc_add_src()
2351 pmc->mca_sfcount[sfmode]++; in ip6_mc_add_src()
2354 err = ip6_mc_add1_src(pmc, sfmode, &psfsrc[i]); in ip6_mc_add_src()
2362 pmc->mca_sfcount[sfmode]--; in ip6_mc_add_src()
2364 ip6_mc_del1_src(pmc, sfmode, &psfsrc[j]); in ip6_mc_add_src()
2365 } else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) { in ip6_mc_add_src()
2369 if (pmc->mca_sfcount[MCAST_EXCLUDE]) in ip6_mc_add_src()
2370 pmc->mca_sfmode = MCAST_EXCLUDE; in ip6_mc_add_src()
2371 else if (pmc->mca_sfcount[MCAST_INCLUDE]) in ip6_mc_add_src()
2372 pmc->mca_sfmode = MCAST_INCLUDE; in ip6_mc_add_src()
2375 pmc->mca_crcount = idev->mc_qrv; in ip6_mc_add_src()
2376 idev->mc_ifc_count = pmc->mca_crcount; in ip6_mc_add_src()
2377 for (psf = pmc->mca_sources; psf; psf = psf->sf_next) in ip6_mc_add_src()
2380 } else if (sf_setstate(pmc)) in ip6_mc_add_src()
2382 spin_unlock_bh(&pmc->mca_lock); in ip6_mc_add_src()
2387 static void ip6_mc_clear_src(struct ifmcaddr6 *pmc) in ip6_mc_clear_src() argument
2391 for (psf = pmc->mca_tomb; psf; psf = nextpsf) { in ip6_mc_clear_src()
2395 pmc->mca_tomb = NULL; in ip6_mc_clear_src()
2396 for (psf = pmc->mca_sources; psf; psf = nextpsf) { in ip6_mc_clear_src()
2400 pmc->mca_sources = NULL; in ip6_mc_clear_src()
2401 pmc->mca_sfmode = MCAST_EXCLUDE; in ip6_mc_clear_src()
2402 pmc->mca_sfcount[MCAST_INCLUDE] = 0; in ip6_mc_clear_src()
2403 pmc->mca_sfcount[MCAST_EXCLUDE] = 1; in ip6_mc_clear_src()
2627 struct ifmcaddr6 *pmc; in ipv6_mc_rejoin_groups() local
2633 for (pmc = idev->mc_list; pmc; pmc = pmc->next) in ipv6_mc_rejoin_groups()
2634 igmp6_join_group(pmc); in ipv6_mc_rejoin_groups()