Lines Matching refs:pmc
168 static int sf_setstate(struct ip_mc_list *pmc);
169 static void sf_markstate(struct ip_mc_list *pmc);
171 static void ip_mc_clear_src(struct ip_mc_list *pmc);
183 #define for_each_pmc_rcu(in_dev, pmc) \ argument
184 for (pmc = rcu_dereference(in_dev->mc_list); \
185 pmc != NULL; \
186 pmc = rcu_dereference(pmc->next_rcu))
188 #define for_each_pmc_rtnl(in_dev, pmc) \ argument
189 for (pmc = rtnl_dereference(in_dev->mc_list); \
190 pmc != NULL; \
191 pmc = rtnl_dereference(pmc->next_rcu))
267 static int is_in(struct ip_mc_list *pmc, struct ip_sf_list *psf, int type, in is_in() argument
275 if (!(pmc->gsquery && !psf->sf_gsresp)) { in is_in()
276 if (pmc->sfmode == MCAST_INCLUDE) in is_in()
283 return pmc->sfcount[MCAST_EXCLUDE] == in is_in()
294 if (pmc->sfcount[MCAST_EXCLUDE] == 0 || in is_in()
297 return pmc->sfcount[MCAST_EXCLUDE] == in is_in()
302 return (pmc->sfmode == MCAST_INCLUDE) ^ sdeleted; in is_in()
304 if (pmc->sfmode == MCAST_INCLUDE) in is_in()
312 igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted) in igmp_scount() argument
317 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_scount()
318 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) in igmp_scount()
423 static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel) in grec_size() argument
425 return sizeof(struct igmpv3_grec) + 4*igmp_scount(pmc, type, gdel, sdel); in grec_size()
428 static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, in add_grhead() argument
431 struct net_device *dev = pmc->interface->dev; in add_grhead()
444 pgr->grec_mca = pmc->multiaddr; in add_grhead()
453 static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, in add_grec() argument
456 struct net_device *dev = pmc->interface->dev; in add_grec()
464 if (pmc->multiaddr == IGMP_ALL_HOSTS) in add_grec()
466 if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports) in add_grec()
480 psf_list = sdeleted ? &pmc->tomb : &pmc->sources; in add_grec()
490 AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { in add_grec()
503 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) { in add_grec()
511 if (((gdeleted && pmc->sfmode == MCAST_EXCLUDE) || in add_grec()
512 (!gdeleted && pmc->crcount)) && in add_grec()
534 skb = add_grhead(skb, pmc, type, &pgr, mtu); in add_grec()
563 if (pmc->crcount || isquery) { in add_grec()
569 skb = add_grhead(skb, pmc, type, &pgr, mtu); in add_grec()
576 pmc->gsquery = 0; /* clear query state on report */ in add_grec()
580 static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) in igmpv3_send_report() argument
586 if (!pmc) { in igmpv3_send_report()
588 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_send_report()
589 if (pmc->multiaddr == IGMP_ALL_HOSTS) in igmpv3_send_report()
591 if (ipv4_is_local_multicast(pmc->multiaddr) && in igmpv3_send_report()
594 spin_lock_bh(&pmc->lock); in igmpv3_send_report()
595 if (pmc->sfcount[MCAST_EXCLUDE]) in igmpv3_send_report()
599 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_report()
600 spin_unlock_bh(&pmc->lock); in igmpv3_send_report()
604 spin_lock_bh(&pmc->lock); in igmpv3_send_report()
605 if (pmc->sfcount[MCAST_EXCLUDE]) in igmpv3_send_report()
609 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_report()
610 spin_unlock_bh(&pmc->lock); in igmpv3_send_report()
640 struct ip_mc_list *pmc, *pmc_prev, *pmc_next; in igmpv3_send_cr() local
649 for (pmc = in_dev->mc_tomb; pmc; pmc = pmc_next) { in igmpv3_send_cr()
650 pmc_next = pmc->next; in igmpv3_send_cr()
651 if (pmc->sfmode == MCAST_INCLUDE) { in igmpv3_send_cr()
654 skb = add_grec(skb, pmc, type, 1, 0); in igmpv3_send_cr()
655 skb = add_grec(skb, pmc, dtype, 1, 1); in igmpv3_send_cr()
657 if (pmc->crcount) { in igmpv3_send_cr()
658 if (pmc->sfmode == MCAST_EXCLUDE) { in igmpv3_send_cr()
660 skb = add_grec(skb, pmc, type, 1, 0); in igmpv3_send_cr()
662 pmc->crcount--; in igmpv3_send_cr()
663 if (pmc->crcount == 0) { in igmpv3_send_cr()
664 igmpv3_clear_zeros(&pmc->tomb); in igmpv3_send_cr()
665 igmpv3_clear_zeros(&pmc->sources); in igmpv3_send_cr()
668 if (pmc->crcount == 0 && !pmc->tomb && !pmc->sources) { in igmpv3_send_cr()
673 in_dev_put(pmc->interface); in igmpv3_send_cr()
674 kfree(pmc); in igmpv3_send_cr()
676 pmc_prev = pmc; in igmpv3_send_cr()
681 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_send_cr()
682 spin_lock_bh(&pmc->lock); in igmpv3_send_cr()
683 if (pmc->sfcount[MCAST_EXCLUDE]) { in igmpv3_send_cr()
690 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_cr()
691 skb = add_grec(skb, pmc, dtype, 0, 1); /* deleted sources */ in igmpv3_send_cr()
694 if (pmc->crcount) { in igmpv3_send_cr()
695 if (pmc->sfmode == MCAST_EXCLUDE) in igmpv3_send_cr()
699 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_cr()
700 pmc->crcount--; in igmpv3_send_cr()
702 spin_unlock_bh(&pmc->lock); in igmpv3_send_cr()
711 static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, in igmp_send_report() argument
720 __be32 group = pmc ? pmc->multiaddr : 0; in igmp_send_report()
726 return igmpv3_send_report(in_dev, pmc); in igmp_send_report()
840 static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) in igmp_xmarksources() argument
846 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_xmarksources()
852 pmc->sfcount[MCAST_EXCLUDE] != in igmp_xmarksources()
861 pmc->gsquery = 0; in igmp_xmarksources()
867 static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) in igmp_marksources() argument
872 if (pmc->sfmode == MCAST_EXCLUDE) in igmp_marksources()
873 return igmp_xmarksources(pmc, nsrcs, srcs); in igmp_marksources()
877 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_marksources()
888 pmc->gsquery = 0; in igmp_marksources()
891 pmc->gsquery = 1; in igmp_marksources()
1138 struct ip_mc_list *pmc; in igmpv3_add_delrec() local
1147 pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); in igmpv3_add_delrec()
1148 if (!pmc) in igmpv3_add_delrec()
1150 spin_lock_init(&pmc->lock); in igmpv3_add_delrec()
1152 pmc->interface = im->interface; in igmpv3_add_delrec()
1154 pmc->multiaddr = im->multiaddr; in igmpv3_add_delrec()
1155 pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv; in igmpv3_add_delrec()
1156 pmc->sfmode = im->sfmode; in igmpv3_add_delrec()
1157 if (pmc->sfmode == MCAST_INCLUDE) { in igmpv3_add_delrec()
1160 pmc->tomb = im->tomb; in igmpv3_add_delrec()
1161 pmc->sources = im->sources; in igmpv3_add_delrec()
1163 for (psf = pmc->sources; psf; psf = psf->sf_next) in igmpv3_add_delrec()
1164 psf->sf_crcount = pmc->crcount; in igmpv3_add_delrec()
1169 pmc->next = in_dev->mc_tomb; in igmpv3_add_delrec()
1170 in_dev->mc_tomb = pmc; in igmpv3_add_delrec()
1179 struct ip_mc_list *pmc, *pmc_prev; in igmpv3_del_delrec() local
1186 for (pmc = in_dev->mc_tomb; pmc; pmc = pmc->next) { in igmpv3_del_delrec()
1187 if (pmc->multiaddr == multiaddr) in igmpv3_del_delrec()
1189 pmc_prev = pmc; in igmpv3_del_delrec()
1191 if (pmc) { in igmpv3_del_delrec()
1193 pmc_prev->next = pmc->next; in igmpv3_del_delrec()
1195 in_dev->mc_tomb = pmc->next; in igmpv3_del_delrec()
1200 if (pmc) { in igmpv3_del_delrec()
1201 im->interface = pmc->interface; in igmpv3_del_delrec()
1203 im->tomb = pmc->tomb; in igmpv3_del_delrec()
1204 im->sources = pmc->sources; in igmpv3_del_delrec()
1210 in_dev_put(pmc->interface); in igmpv3_del_delrec()
1211 kfree(pmc); in igmpv3_del_delrec()
1221 struct ip_mc_list *pmc, *nextpmc; in igmpv3_clear_delrec() local
1224 pmc = in_dev->mc_tomb; in igmpv3_clear_delrec()
1228 for (; pmc; pmc = nextpmc) { in igmpv3_clear_delrec()
1229 nextpmc = pmc->next; in igmpv3_clear_delrec()
1230 ip_mc_clear_src(pmc); in igmpv3_clear_delrec()
1231 in_dev_put(pmc->interface); in igmpv3_clear_delrec()
1232 kfree(pmc); in igmpv3_clear_delrec()
1236 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_clear_delrec()
1239 spin_lock_bh(&pmc->lock); in igmpv3_clear_delrec()
1240 psf = pmc->tomb; in igmpv3_clear_delrec()
1241 pmc->tomb = NULL; in igmpv3_clear_delrec()
1242 spin_unlock_bh(&pmc->lock); in igmpv3_clear_delrec()
1681 struct ip_mc_list *pmc; in ip_mc_unmap() local
1685 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_unmap()
1686 igmp_group_dropped(pmc); in ip_mc_unmap()
1691 struct ip_mc_list *pmc; in ip_mc_remap() local
1695 for_each_pmc_rtnl(in_dev, pmc) { in ip_mc_remap()
1697 igmpv3_del_delrec(in_dev, pmc); in ip_mc_remap()
1699 igmp_group_added(pmc); in ip_mc_remap()
1707 struct ip_mc_list *pmc; in ip_mc_down() local
1711 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_down()
1712 igmp_group_dropped(pmc); in ip_mc_down()
1746 struct ip_mc_list *pmc; in ip_mc_up() local
1758 for_each_pmc_rtnl(in_dev, pmc) { in ip_mc_up()
1760 igmpv3_del_delrec(in_dev, pmc); in ip_mc_up()
1762 igmp_group_added(pmc); in ip_mc_up()
1825 static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, in ip_mc_del1_src() argument
1832 for (psf = pmc->sources; psf; psf = psf->sf_next) { in ip_mc_del1_src()
1843 ip_rt_multicast_event(pmc->interface); in ip_mc_del1_src()
1847 struct in_device *in_dev = pmc->interface; in ip_mc_del1_src()
1855 pmc->sources = psf->sf_next; in ip_mc_del1_src()
1860 psf->sf_next = pmc->tomb; in ip_mc_del1_src()
1861 pmc->tomb = psf; in ip_mc_del1_src()
1877 struct ip_mc_list *pmc; in ip_mc_del_src() local
1884 for_each_pmc_rcu(in_dev, pmc) { in ip_mc_del_src()
1885 if (*pmca == pmc->multiaddr) in ip_mc_del_src()
1888 if (!pmc) { in ip_mc_del_src()
1893 spin_lock_bh(&pmc->lock); in ip_mc_del_src()
1896 sf_markstate(pmc); in ip_mc_del_src()
1900 if (!pmc->sfcount[sfmode]) in ip_mc_del_src()
1902 pmc->sfcount[sfmode]--; in ip_mc_del_src()
1906 int rv = ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); in ip_mc_del_src()
1912 if (pmc->sfmode == MCAST_EXCLUDE && in ip_mc_del_src()
1913 pmc->sfcount[MCAST_EXCLUDE] == 0 && in ip_mc_del_src()
1914 pmc->sfcount[MCAST_INCLUDE]) { in ip_mc_del_src()
1921 pmc->sfmode = MCAST_INCLUDE; in ip_mc_del_src()
1923 pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv; in ip_mc_del_src()
1924 in_dev->mr_ifc_count = pmc->crcount; in ip_mc_del_src()
1925 for (psf = pmc->sources; psf; psf = psf->sf_next) in ip_mc_del_src()
1927 igmp_ifc_event(pmc->interface); in ip_mc_del_src()
1928 } else if (sf_setstate(pmc) || changerec) { in ip_mc_del_src()
1929 igmp_ifc_event(pmc->interface); in ip_mc_del_src()
1933 spin_unlock_bh(&pmc->lock); in ip_mc_del_src()
1940 static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode, in ip_mc_add1_src() argument
1946 for (psf = pmc->sources; psf; psf = psf->sf_next) { in ip_mc_add1_src()
1959 pmc->sources = psf; in ip_mc_add1_src()
1963 ip_rt_multicast_event(pmc->interface); in ip_mc_add1_src()
1969 static void sf_markstate(struct ip_mc_list *pmc) in sf_markstate() argument
1972 int mca_xcount = pmc->sfcount[MCAST_EXCLUDE]; in sf_markstate()
1974 for (psf = pmc->sources; psf; psf = psf->sf_next) in sf_markstate()
1975 if (pmc->sfcount[MCAST_EXCLUDE]) { in sf_markstate()
1983 static int sf_setstate(struct ip_mc_list *pmc) in sf_setstate() argument
1986 int mca_xcount = pmc->sfcount[MCAST_EXCLUDE]; in sf_setstate()
1987 int qrv = pmc->interface->mr_qrv; in sf_setstate()
1991 for (psf = pmc->sources; psf; psf = psf->sf_next) { in sf_setstate()
1992 if (pmc->sfcount[MCAST_EXCLUDE]) { in sf_setstate()
2001 for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) { in sf_setstate()
2010 pmc->tomb = dpsf->sf_next; in sf_setstate()
2023 for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) in sf_setstate()
2032 dpsf->sf_next = pmc->tomb; in sf_setstate()
2033 pmc->tomb = dpsf; in sf_setstate()
2049 struct ip_mc_list *pmc; in ip_mc_add_src() local
2056 for_each_pmc_rcu(in_dev, pmc) { in ip_mc_add_src()
2057 if (*pmca == pmc->multiaddr) in ip_mc_add_src()
2060 if (!pmc) { in ip_mc_add_src()
2065 spin_lock_bh(&pmc->lock); in ip_mc_add_src()
2069 sf_markstate(pmc); in ip_mc_add_src()
2071 isexclude = pmc->sfmode == MCAST_EXCLUDE; in ip_mc_add_src()
2073 pmc->sfcount[sfmode]++; in ip_mc_add_src()
2076 err = ip_mc_add1_src(pmc, sfmode, &psfsrc[i]); in ip_mc_add_src()
2084 pmc->sfcount[sfmode]--; in ip_mc_add_src()
2086 (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]); in ip_mc_add_src()
2087 } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { in ip_mc_add_src()
2090 struct net *net = dev_net(pmc->interface->dev); in ip_mc_add_src()
2091 in_dev = pmc->interface; in ip_mc_add_src()
2095 if (pmc->sfcount[MCAST_EXCLUDE]) in ip_mc_add_src()
2096 pmc->sfmode = MCAST_EXCLUDE; in ip_mc_add_src()
2097 else if (pmc->sfcount[MCAST_INCLUDE]) in ip_mc_add_src()
2098 pmc->sfmode = MCAST_INCLUDE; in ip_mc_add_src()
2102 pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv; in ip_mc_add_src()
2103 in_dev->mr_ifc_count = pmc->crcount; in ip_mc_add_src()
2104 for (psf = pmc->sources; psf; psf = psf->sf_next) in ip_mc_add_src()
2107 } else if (sf_setstate(pmc)) { in ip_mc_add_src()
2111 spin_unlock_bh(&pmc->lock); in ip_mc_add_src()
2115 static void ip_mc_clear_src(struct ip_mc_list *pmc) in ip_mc_clear_src() argument
2119 spin_lock_bh(&pmc->lock); in ip_mc_clear_src()
2120 tomb = pmc->tomb; in ip_mc_clear_src()
2121 pmc->tomb = NULL; in ip_mc_clear_src()
2122 sources = pmc->sources; in ip_mc_clear_src()
2123 pmc->sources = NULL; in ip_mc_clear_src()
2124 pmc->sfmode = MCAST_EXCLUDE; in ip_mc_clear_src()
2125 pmc->sfcount[MCAST_INCLUDE] = 0; in ip_mc_clear_src()
2126 pmc->sfcount[MCAST_EXCLUDE] = 1; in ip_mc_clear_src()
2127 spin_unlock_bh(&pmc->lock); in ip_mc_clear_src()
2281 struct ip_mc_socklist *pmc; in ip_mc_source() local
2305 for_each_pmc_rtnl(inet, pmc) { in ip_mc_source()
2306 if ((pmc->multi.imr_multiaddr.s_addr == in ip_mc_source()
2308 (pmc->multi.imr_ifindex == imr.imr_ifindex)) in ip_mc_source()
2311 if (!pmc) { /* must have a prior join */ in ip_mc_source()
2316 if (pmc->sflist) { in ip_mc_source()
2317 if (pmc->sfmode != omode) { in ip_mc_source()
2321 } else if (pmc->sfmode != omode) { in ip_mc_source()
2324 ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, pmc->sfmode, 0, in ip_mc_source()
2326 pmc->sfmode = omode; in ip_mc_source()
2329 psl = rtnl_dereference(pmc->sflist); in ip_mc_source()
2385 rcu_assign_pointer(pmc->sflist, newpsl); in ip_mc_source()
2416 struct ip_mc_socklist *pmc; in ip_mc_msfilter() local
2447 for_each_pmc_rtnl(inet, pmc) { in ip_mc_msfilter()
2448 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && in ip_mc_msfilter()
2449 pmc->multi.imr_ifindex == imr.imr_ifindex) in ip_mc_msfilter()
2452 if (!pmc) { /* must have a prior join */ in ip_mc_msfilter()
2477 psl = rtnl_dereference(pmc->sflist); in ip_mc_msfilter()
2479 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, in ip_mc_msfilter()
2485 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, in ip_mc_msfilter()
2487 rcu_assign_pointer(pmc->sflist, newpsl); in ip_mc_msfilter()
2488 pmc->sfmode = msf->imsf_fmode; in ip_mc_msfilter()
2502 struct ip_mc_socklist *pmc; in ip_mc_msfget() local
2524 for_each_pmc_rtnl(inet, pmc) { in ip_mc_msfget()
2525 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && in ip_mc_msfget()
2526 pmc->multi.imr_ifindex == imr.imr_ifindex) in ip_mc_msfget()
2529 if (!pmc) /* must have a prior join */ in ip_mc_msfget()
2531 msf->imsf_fmode = pmc->sfmode; in ip_mc_msfget()
2532 psl = rtnl_dereference(pmc->sflist); in ip_mc_msfget()
2560 struct ip_mc_socklist *pmc; in ip_mc_gsfget() local
2575 for_each_pmc_rtnl(inet, pmc) { in ip_mc_gsfget()
2576 if (pmc->multi.imr_multiaddr.s_addr == addr && in ip_mc_gsfget()
2577 pmc->multi.imr_ifindex == gsf->gf_interface) in ip_mc_gsfget()
2580 if (!pmc) /* must have a prior join */ in ip_mc_gsfget()
2582 gsf->gf_fmode = pmc->sfmode; in ip_mc_gsfget()
2583 psl = rtnl_dereference(pmc->sflist); in ip_mc_gsfget()
2613 struct ip_mc_socklist *pmc; in ip_mc_sf_allow() local
2623 for_each_pmc_rcu(inet, pmc) { in ip_mc_sf_allow()
2624 if (pmc->multi.imr_multiaddr.s_addr == loc_addr && in ip_mc_sf_allow()
2625 (pmc->multi.imr_ifindex == dif || in ip_mc_sf_allow()
2626 (sdif && pmc->multi.imr_ifindex == sdif))) in ip_mc_sf_allow()
2630 if (!pmc) in ip_mc_sf_allow()
2632 psl = rcu_dereference(pmc->sflist); in ip_mc_sf_allow()
2633 ret = (pmc->sfmode == MCAST_EXCLUDE); in ip_mc_sf_allow()
2642 if (pmc->sfmode == MCAST_INCLUDE && i >= psl->sl_count) in ip_mc_sf_allow()
2644 if (pmc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) in ip_mc_sf_allow()