Lines Matching refs:pmc

173 static int sf_setstate(struct ip_mc_list *pmc);
174 static void sf_markstate(struct ip_mc_list *pmc);
176 static void ip_mc_clear_src(struct ip_mc_list *pmc);
188 #define for_each_pmc_rcu(in_dev, pmc) \ argument
189 for (pmc = rcu_dereference(in_dev->mc_list); \
190 pmc != NULL; \
191 pmc = rcu_dereference(pmc->next_rcu))
193 #define for_each_pmc_rtnl(in_dev, pmc) \ argument
194 for (pmc = rtnl_dereference(in_dev->mc_list); \
195 pmc != NULL; \
196 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()
402 static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel) in grec_size() argument
404 return sizeof(struct igmpv3_grec) + 4*igmp_scount(pmc, type, gdel, sdel); in grec_size()
407 static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, in add_grhead() argument
410 struct net_device *dev = pmc->interface->dev; in add_grhead()
422 pgr->grec_mca = pmc->multiaddr; in add_grhead()
431 static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, in add_grec() argument
434 struct net_device *dev = pmc->interface->dev; in add_grec()
440 if (pmc->multiaddr == IGMP_ALL_HOSTS) in add_grec()
442 if (ipv4_is_local_multicast(pmc->multiaddr) && !sysctl_igmp_llm_reports) in add_grec()
452 psf_list = sdeleted ? &pmc->tomb : &pmc->sources; in add_grec()
462 AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { in add_grec()
475 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) { in add_grec()
497 skb = add_grhead(skb, pmc, type, &pgr); in add_grec()
525 if (pmc->crcount || isquery) { in add_grec()
531 skb = add_grhead(skb, pmc, type, &pgr); in add_grec()
538 pmc->gsquery = 0; /* clear query state on report */ in add_grec()
542 static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) in igmpv3_send_report() argument
547 if (!pmc) { in igmpv3_send_report()
549 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_send_report()
550 if (pmc->multiaddr == IGMP_ALL_HOSTS) in igmpv3_send_report()
552 if (ipv4_is_local_multicast(pmc->multiaddr) && in igmpv3_send_report()
555 spin_lock_bh(&pmc->lock); in igmpv3_send_report()
556 if (pmc->sfcount[MCAST_EXCLUDE]) in igmpv3_send_report()
560 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_report()
561 spin_unlock_bh(&pmc->lock); in igmpv3_send_report()
565 spin_lock_bh(&pmc->lock); in igmpv3_send_report()
566 if (pmc->sfcount[MCAST_EXCLUDE]) in igmpv3_send_report()
570 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_report()
571 spin_unlock_bh(&pmc->lock); in igmpv3_send_report()
601 struct ip_mc_list *pmc, *pmc_prev, *pmc_next; in igmpv3_send_cr() local
610 for (pmc = in_dev->mc_tomb; pmc; pmc = pmc_next) { in igmpv3_send_cr()
611 pmc_next = pmc->next; in igmpv3_send_cr()
612 if (pmc->sfmode == MCAST_INCLUDE) { in igmpv3_send_cr()
615 skb = add_grec(skb, pmc, type, 1, 0); in igmpv3_send_cr()
616 skb = add_grec(skb, pmc, dtype, 1, 1); in igmpv3_send_cr()
618 if (pmc->crcount) { in igmpv3_send_cr()
619 if (pmc->sfmode == MCAST_EXCLUDE) { in igmpv3_send_cr()
621 skb = add_grec(skb, pmc, type, 1, 0); in igmpv3_send_cr()
623 pmc->crcount--; in igmpv3_send_cr()
624 if (pmc->crcount == 0) { in igmpv3_send_cr()
625 igmpv3_clear_zeros(&pmc->tomb); in igmpv3_send_cr()
626 igmpv3_clear_zeros(&pmc->sources); in igmpv3_send_cr()
629 if (pmc->crcount == 0 && !pmc->tomb && !pmc->sources) { in igmpv3_send_cr()
634 in_dev_put(pmc->interface); in igmpv3_send_cr()
635 kfree(pmc); in igmpv3_send_cr()
637 pmc_prev = pmc; in igmpv3_send_cr()
642 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_send_cr()
643 spin_lock_bh(&pmc->lock); in igmpv3_send_cr()
644 if (pmc->sfcount[MCAST_EXCLUDE]) { in igmpv3_send_cr()
651 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_cr()
652 skb = add_grec(skb, pmc, dtype, 0, 1); /* deleted sources */ in igmpv3_send_cr()
655 if (pmc->crcount) { in igmpv3_send_cr()
656 if (pmc->sfmode == MCAST_EXCLUDE) in igmpv3_send_cr()
660 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_cr()
661 pmc->crcount--; in igmpv3_send_cr()
663 spin_unlock_bh(&pmc->lock); in igmpv3_send_cr()
672 static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, in igmp_send_report() argument
681 __be32 group = pmc ? pmc->multiaddr : 0; in igmp_send_report()
687 return igmpv3_send_report(in_dev, pmc); in igmp_send_report()
801 static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) in igmp_xmarksources() argument
807 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_xmarksources()
813 pmc->sfcount[MCAST_EXCLUDE] != in igmp_xmarksources()
822 pmc->gsquery = 0; in igmp_xmarksources()
828 static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) in igmp_marksources() argument
833 if (pmc->sfmode == MCAST_EXCLUDE) in igmp_marksources()
834 return igmp_xmarksources(pmc, nsrcs, srcs); in igmp_marksources()
838 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_marksources()
849 pmc->gsquery = 0; in igmp_marksources()
852 pmc->gsquery = 1; in igmp_marksources()
1089 struct ip_mc_list *pmc; in igmpv3_add_delrec() local
1097 pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); in igmpv3_add_delrec()
1098 if (!pmc) in igmpv3_add_delrec()
1101 pmc->interface = im->interface; in igmpv3_add_delrec()
1103 pmc->multiaddr = im->multiaddr; in igmpv3_add_delrec()
1104 pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv; in igmpv3_add_delrec()
1105 pmc->sfmode = im->sfmode; in igmpv3_add_delrec()
1106 if (pmc->sfmode == MCAST_INCLUDE) { in igmpv3_add_delrec()
1109 pmc->tomb = im->tomb; in igmpv3_add_delrec()
1110 pmc->sources = im->sources; in igmpv3_add_delrec()
1112 for (psf = pmc->sources; psf; psf = psf->sf_next) in igmpv3_add_delrec()
1113 psf->sf_crcount = pmc->crcount; in igmpv3_add_delrec()
1118 pmc->next = in_dev->mc_tomb; in igmpv3_add_delrec()
1119 in_dev->mc_tomb = pmc; in igmpv3_add_delrec()
1125 struct ip_mc_list *pmc, *pmc_prev; in igmpv3_del_delrec() local
1130 for (pmc = in_dev->mc_tomb; pmc; pmc = pmc->next) { in igmpv3_del_delrec()
1131 if (pmc->multiaddr == multiaddr) in igmpv3_del_delrec()
1133 pmc_prev = pmc; in igmpv3_del_delrec()
1135 if (pmc) { in igmpv3_del_delrec()
1137 pmc_prev->next = pmc->next; in igmpv3_del_delrec()
1139 in_dev->mc_tomb = pmc->next; in igmpv3_del_delrec()
1142 if (pmc) { in igmpv3_del_delrec()
1143 for (psf = pmc->tomb; psf; psf = psf_next) { in igmpv3_del_delrec()
1147 in_dev_put(pmc->interface); in igmpv3_del_delrec()
1148 kfree(pmc); in igmpv3_del_delrec()
1154 struct ip_mc_list *pmc, *nextpmc; in igmpv3_clear_delrec() local
1157 pmc = in_dev->mc_tomb; in igmpv3_clear_delrec()
1161 for (; pmc; pmc = nextpmc) { in igmpv3_clear_delrec()
1162 nextpmc = pmc->next; in igmpv3_clear_delrec()
1163 ip_mc_clear_src(pmc); in igmpv3_clear_delrec()
1164 in_dev_put(pmc->interface); in igmpv3_clear_delrec()
1165 kfree(pmc); in igmpv3_clear_delrec()
1169 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_clear_delrec()
1172 spin_lock_bh(&pmc->lock); in igmpv3_clear_delrec()
1173 psf = pmc->tomb; in igmpv3_clear_delrec()
1174 pmc->tomb = NULL; in igmpv3_clear_delrec()
1175 spin_unlock_bh(&pmc->lock); in igmpv3_clear_delrec()
1597 struct ip_mc_list *pmc; in ip_mc_unmap() local
1601 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_unmap()
1602 igmp_group_dropped(pmc); in ip_mc_unmap()
1607 struct ip_mc_list *pmc; in ip_mc_remap() local
1611 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_remap()
1612 igmp_group_added(pmc); in ip_mc_remap()
1619 struct ip_mc_list *pmc; in ip_mc_down() local
1623 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_down()
1624 igmp_group_dropped(pmc); in ip_mc_down()
1658 struct ip_mc_list *pmc; in ip_mc_up() local
1667 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_up()
1668 igmp_group_added(pmc); in ip_mc_up()
1735 static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, in ip_mc_del1_src() argument
1742 for (psf = pmc->sources; psf; psf = psf->sf_next) { in ip_mc_del1_src()
1753 ip_rt_multicast_event(pmc->interface); in ip_mc_del1_src()
1757 struct in_device *in_dev = pmc->interface; in ip_mc_del1_src()
1764 pmc->sources = psf->sf_next; in ip_mc_del1_src()
1769 psf->sf_next = pmc->tomb; in ip_mc_del1_src()
1770 pmc->tomb = psf; in ip_mc_del1_src()
1786 struct ip_mc_list *pmc; in ip_mc_del_src() local
1793 for_each_pmc_rcu(in_dev, pmc) { in ip_mc_del_src()
1794 if (*pmca == pmc->multiaddr) in ip_mc_del_src()
1797 if (!pmc) { in ip_mc_del_src()
1802 spin_lock_bh(&pmc->lock); in ip_mc_del_src()
1805 sf_markstate(pmc); in ip_mc_del_src()
1809 if (!pmc->sfcount[sfmode]) in ip_mc_del_src()
1811 pmc->sfcount[sfmode]--; in ip_mc_del_src()
1815 int rv = ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); in ip_mc_del_src()
1821 if (pmc->sfmode == MCAST_EXCLUDE && in ip_mc_del_src()
1822 pmc->sfcount[MCAST_EXCLUDE] == 0 && in ip_mc_del_src()
1823 pmc->sfcount[MCAST_INCLUDE]) { in ip_mc_del_src()
1829 pmc->sfmode = MCAST_INCLUDE; in ip_mc_del_src()
1831 pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv; in ip_mc_del_src()
1832 in_dev->mr_ifc_count = pmc->crcount; in ip_mc_del_src()
1833 for (psf = pmc->sources; psf; psf = psf->sf_next) in ip_mc_del_src()
1835 igmp_ifc_event(pmc->interface); in ip_mc_del_src()
1836 } else if (sf_setstate(pmc) || changerec) { in ip_mc_del_src()
1837 igmp_ifc_event(pmc->interface); in ip_mc_del_src()
1841 spin_unlock_bh(&pmc->lock); in ip_mc_del_src()
1848 static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode, in ip_mc_add1_src() argument
1854 for (psf = pmc->sources; psf; psf = psf->sf_next) { in ip_mc_add1_src()
1867 pmc->sources = psf; in ip_mc_add1_src()
1871 ip_rt_multicast_event(pmc->interface); in ip_mc_add1_src()
1877 static void sf_markstate(struct ip_mc_list *pmc) in sf_markstate() argument
1880 int mca_xcount = pmc->sfcount[MCAST_EXCLUDE]; in sf_markstate()
1882 for (psf = pmc->sources; psf; psf = psf->sf_next) in sf_markstate()
1883 if (pmc->sfcount[MCAST_EXCLUDE]) { in sf_markstate()
1891 static int sf_setstate(struct ip_mc_list *pmc) in sf_setstate() argument
1894 int mca_xcount = pmc->sfcount[MCAST_EXCLUDE]; in sf_setstate()
1895 int qrv = pmc->interface->mr_qrv; in sf_setstate()
1899 for (psf = pmc->sources; psf; psf = psf->sf_next) { in sf_setstate()
1900 if (pmc->sfcount[MCAST_EXCLUDE]) { in sf_setstate()
1909 for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) { in sf_setstate()
1918 pmc->tomb = dpsf->sf_next; in sf_setstate()
1931 for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) in sf_setstate()
1940 dpsf->sf_next = pmc->tomb; in sf_setstate()
1941 pmc->tomb = dpsf; in sf_setstate()
1957 struct ip_mc_list *pmc; in ip_mc_add_src() local
1964 for_each_pmc_rcu(in_dev, pmc) { in ip_mc_add_src()
1965 if (*pmca == pmc->multiaddr) in ip_mc_add_src()
1968 if (!pmc) { in ip_mc_add_src()
1973 spin_lock_bh(&pmc->lock); in ip_mc_add_src()
1977 sf_markstate(pmc); in ip_mc_add_src()
1979 isexclude = pmc->sfmode == MCAST_EXCLUDE; in ip_mc_add_src()
1981 pmc->sfcount[sfmode]++; in ip_mc_add_src()
1984 err = ip_mc_add1_src(pmc, sfmode, &psfsrc[i]); in ip_mc_add_src()
1992 pmc->sfcount[sfmode]--; in ip_mc_add_src()
1994 (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]); in ip_mc_add_src()
1995 } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { in ip_mc_add_src()
1998 in_dev = pmc->interface; in ip_mc_add_src()
2002 if (pmc->sfcount[MCAST_EXCLUDE]) in ip_mc_add_src()
2003 pmc->sfmode = MCAST_EXCLUDE; in ip_mc_add_src()
2004 else if (pmc->sfcount[MCAST_INCLUDE]) in ip_mc_add_src()
2005 pmc->sfmode = MCAST_INCLUDE; in ip_mc_add_src()
2009 pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv; in ip_mc_add_src()
2010 in_dev->mr_ifc_count = pmc->crcount; in ip_mc_add_src()
2011 for (psf = pmc->sources; psf; psf = psf->sf_next) in ip_mc_add_src()
2014 } else if (sf_setstate(pmc)) { in ip_mc_add_src()
2018 spin_unlock_bh(&pmc->lock); in ip_mc_add_src()
2022 static void ip_mc_clear_src(struct ip_mc_list *pmc) in ip_mc_clear_src() argument
2026 for (psf = pmc->tomb; psf; psf = nextpsf) { in ip_mc_clear_src()
2030 pmc->tomb = NULL; in ip_mc_clear_src()
2031 for (psf = pmc->sources; psf; psf = nextpsf) { in ip_mc_clear_src()
2035 pmc->sources = NULL; in ip_mc_clear_src()
2036 pmc->sfmode = MCAST_EXCLUDE; in ip_mc_clear_src()
2037 pmc->sfcount[MCAST_INCLUDE] = 0; in ip_mc_clear_src()
2038 pmc->sfcount[MCAST_EXCLUDE] = 1; in ip_mc_clear_src()
2168 struct ip_mc_socklist *pmc; in ip_mc_source() local
2192 for_each_pmc_rtnl(inet, pmc) { in ip_mc_source()
2193 if ((pmc->multi.imr_multiaddr.s_addr == in ip_mc_source()
2195 (pmc->multi.imr_ifindex == imr.imr_ifindex)) in ip_mc_source()
2198 if (!pmc) { /* must have a prior join */ in ip_mc_source()
2203 if (pmc->sflist) { in ip_mc_source()
2204 if (pmc->sfmode != omode) { in ip_mc_source()
2208 } else if (pmc->sfmode != omode) { in ip_mc_source()
2211 ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, pmc->sfmode, 0, in ip_mc_source()
2213 pmc->sfmode = omode; in ip_mc_source()
2216 psl = rtnl_dereference(pmc->sflist); in ip_mc_source()
2272 rcu_assign_pointer(pmc->sflist, newpsl); in ip_mc_source()
2303 struct ip_mc_socklist *pmc; in ip_mc_msfilter() local
2334 for_each_pmc_rtnl(inet, pmc) { in ip_mc_msfilter()
2335 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && in ip_mc_msfilter()
2336 pmc->multi.imr_ifindex == imr.imr_ifindex) in ip_mc_msfilter()
2339 if (!pmc) { /* must have a prior join */ in ip_mc_msfilter()
2364 psl = rtnl_dereference(pmc->sflist); in ip_mc_msfilter()
2366 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, in ip_mc_msfilter()
2372 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, in ip_mc_msfilter()
2374 rcu_assign_pointer(pmc->sflist, newpsl); in ip_mc_msfilter()
2375 pmc->sfmode = msf->imsf_fmode; in ip_mc_msfilter()
2389 struct ip_mc_socklist *pmc; in ip_mc_msfget() local
2411 for_each_pmc_rtnl(inet, pmc) { in ip_mc_msfget()
2412 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && in ip_mc_msfget()
2413 pmc->multi.imr_ifindex == imr.imr_ifindex) in ip_mc_msfget()
2416 if (!pmc) /* must have a prior join */ in ip_mc_msfget()
2418 msf->imsf_fmode = pmc->sfmode; in ip_mc_msfget()
2419 psl = rtnl_dereference(pmc->sflist); in ip_mc_msfget()
2447 struct ip_mc_socklist *pmc; in ip_mc_gsfget() local
2462 for_each_pmc_rtnl(inet, pmc) { in ip_mc_gsfget()
2463 if (pmc->multi.imr_multiaddr.s_addr == addr && in ip_mc_gsfget()
2464 pmc->multi.imr_ifindex == gsf->gf_interface) in ip_mc_gsfget()
2467 if (!pmc) /* must have a prior join */ in ip_mc_gsfget()
2469 gsf->gf_fmode = pmc->sfmode; in ip_mc_gsfget()
2470 psl = rtnl_dereference(pmc->sflist); in ip_mc_gsfget()
2499 struct ip_mc_socklist *pmc; in ip_mc_sf_allow() local
2509 for_each_pmc_rcu(inet, pmc) { in ip_mc_sf_allow()
2510 if (pmc->multi.imr_multiaddr.s_addr == loc_addr && in ip_mc_sf_allow()
2511 pmc->multi.imr_ifindex == dif) in ip_mc_sf_allow()
2515 if (!pmc) in ip_mc_sf_allow()
2517 psl = rcu_dereference(pmc->sflist); in ip_mc_sf_allow()
2518 ret = (pmc->sfmode == MCAST_EXCLUDE); in ip_mc_sf_allow()
2527 if (pmc->sfmode == MCAST_INCLUDE && i >= psl->sl_count) in ip_mc_sf_allow()
2529 if (pmc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) in ip_mc_sf_allow()