Lines Matching refs:pmc

170 static int sf_setstate(struct ip_mc_list *pmc);
171 static void sf_markstate(struct ip_mc_list *pmc);
173 static void ip_mc_clear_src(struct ip_mc_list *pmc);
185 #define for_each_pmc_rcu(in_dev, pmc) \ argument
186 for (pmc = rcu_dereference(in_dev->mc_list); \
187 pmc != NULL; \
188 pmc = rcu_dereference(pmc->next_rcu))
190 #define for_each_pmc_rtnl(in_dev, pmc) \ argument
191 for (pmc = rtnl_dereference(in_dev->mc_list); \
192 pmc != NULL; \
193 pmc = rtnl_dereference(pmc->next_rcu))
264 static int is_in(struct ip_mc_list *pmc, struct ip_sf_list *psf, int type, in is_in() argument
272 if (!(pmc->gsquery && !psf->sf_gsresp)) { in is_in()
273 if (pmc->sfmode == MCAST_INCLUDE) in is_in()
280 return pmc->sfcount[MCAST_EXCLUDE] == in is_in()
291 if (pmc->sfcount[MCAST_EXCLUDE] == 0 || in is_in()
294 return pmc->sfcount[MCAST_EXCLUDE] == in is_in()
299 return (pmc->sfmode == MCAST_INCLUDE) ^ sdeleted; in is_in()
301 if (pmc->sfmode == MCAST_INCLUDE) in is_in()
309 igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted) in igmp_scount() argument
314 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_scount()
315 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) in igmp_scount()
400 static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel) in grec_size() argument
402 return sizeof(struct igmpv3_grec) + 4*igmp_scount(pmc, type, gdel, sdel); in grec_size()
405 static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, in add_grhead() argument
408 struct net_device *dev = pmc->interface->dev; in add_grhead()
420 pgr->grec_mca = pmc->multiaddr; in add_grhead()
429 static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, in add_grec() argument
432 struct net_device *dev = pmc->interface->dev; in add_grec()
438 if (pmc->multiaddr == IGMP_ALL_HOSTS) in add_grec()
448 psf_list = sdeleted ? &pmc->tomb : &pmc->sources; in add_grec()
458 AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { in add_grec()
471 if (!is_in(pmc, psf, type, gdeleted, sdeleted)) { in add_grec()
493 skb = add_grhead(skb, pmc, type, &pgr); in add_grec()
521 if (pmc->crcount || isquery) { in add_grec()
527 skb = add_grhead(skb, pmc, type, &pgr); in add_grec()
534 pmc->gsquery = 0; /* clear query state on report */ in add_grec()
538 static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) in igmpv3_send_report() argument
543 if (!pmc) { in igmpv3_send_report()
545 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_send_report()
546 if (pmc->multiaddr == IGMP_ALL_HOSTS) in igmpv3_send_report()
548 spin_lock_bh(&pmc->lock); in igmpv3_send_report()
549 if (pmc->sfcount[MCAST_EXCLUDE]) in igmpv3_send_report()
553 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_report()
554 spin_unlock_bh(&pmc->lock); in igmpv3_send_report()
558 spin_lock_bh(&pmc->lock); in igmpv3_send_report()
559 if (pmc->sfcount[MCAST_EXCLUDE]) in igmpv3_send_report()
563 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_report()
564 spin_unlock_bh(&pmc->lock); in igmpv3_send_report()
594 struct ip_mc_list *pmc, *pmc_prev, *pmc_next; in igmpv3_send_cr() local
603 for (pmc = in_dev->mc_tomb; pmc; pmc = pmc_next) { in igmpv3_send_cr()
604 pmc_next = pmc->next; in igmpv3_send_cr()
605 if (pmc->sfmode == MCAST_INCLUDE) { in igmpv3_send_cr()
608 skb = add_grec(skb, pmc, type, 1, 0); in igmpv3_send_cr()
609 skb = add_grec(skb, pmc, dtype, 1, 1); in igmpv3_send_cr()
611 if (pmc->crcount) { in igmpv3_send_cr()
612 if (pmc->sfmode == MCAST_EXCLUDE) { in igmpv3_send_cr()
614 skb = add_grec(skb, pmc, type, 1, 0); in igmpv3_send_cr()
616 pmc->crcount--; in igmpv3_send_cr()
617 if (pmc->crcount == 0) { in igmpv3_send_cr()
618 igmpv3_clear_zeros(&pmc->tomb); in igmpv3_send_cr()
619 igmpv3_clear_zeros(&pmc->sources); in igmpv3_send_cr()
622 if (pmc->crcount == 0 && !pmc->tomb && !pmc->sources) { in igmpv3_send_cr()
627 in_dev_put(pmc->interface); in igmpv3_send_cr()
628 kfree(pmc); in igmpv3_send_cr()
630 pmc_prev = pmc; in igmpv3_send_cr()
635 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_send_cr()
636 spin_lock_bh(&pmc->lock); in igmpv3_send_cr()
637 if (pmc->sfcount[MCAST_EXCLUDE]) { in igmpv3_send_cr()
644 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_cr()
645 skb = add_grec(skb, pmc, dtype, 0, 1); /* deleted sources */ in igmpv3_send_cr()
648 if (pmc->crcount) { in igmpv3_send_cr()
649 if (pmc->sfmode == MCAST_EXCLUDE) in igmpv3_send_cr()
653 skb = add_grec(skb, pmc, type, 0, 0); in igmpv3_send_cr()
654 pmc->crcount--; in igmpv3_send_cr()
656 spin_unlock_bh(&pmc->lock); in igmpv3_send_cr()
665 static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, in igmp_send_report() argument
674 __be32 group = pmc ? pmc->multiaddr : 0; in igmp_send_report()
680 return igmpv3_send_report(in_dev, pmc); in igmp_send_report()
790 static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) in igmp_xmarksources() argument
796 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_xmarksources()
802 pmc->sfcount[MCAST_EXCLUDE] != in igmp_xmarksources()
811 pmc->gsquery = 0; in igmp_xmarksources()
817 static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) in igmp_marksources() argument
822 if (pmc->sfmode == MCAST_EXCLUDE) in igmp_marksources()
823 return igmp_xmarksources(pmc, nsrcs, srcs); in igmp_marksources()
827 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_marksources()
838 pmc->gsquery = 0; in igmp_marksources()
841 pmc->gsquery = 1; in igmp_marksources()
1073 struct ip_mc_list *pmc; in igmpv3_add_delrec() local
1081 pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); in igmpv3_add_delrec()
1082 if (!pmc) in igmpv3_add_delrec()
1085 pmc->interface = im->interface; in igmpv3_add_delrec()
1087 pmc->multiaddr = im->multiaddr; in igmpv3_add_delrec()
1088 pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv; in igmpv3_add_delrec()
1089 pmc->sfmode = im->sfmode; in igmpv3_add_delrec()
1090 if (pmc->sfmode == MCAST_INCLUDE) { in igmpv3_add_delrec()
1093 pmc->tomb = im->tomb; in igmpv3_add_delrec()
1094 pmc->sources = im->sources; in igmpv3_add_delrec()
1096 for (psf = pmc->sources; psf; psf = psf->sf_next) in igmpv3_add_delrec()
1097 psf->sf_crcount = pmc->crcount; in igmpv3_add_delrec()
1102 pmc->next = in_dev->mc_tomb; in igmpv3_add_delrec()
1103 in_dev->mc_tomb = pmc; in igmpv3_add_delrec()
1109 struct ip_mc_list *pmc, *pmc_prev; in igmpv3_del_delrec() local
1114 for (pmc = in_dev->mc_tomb; pmc; pmc = pmc->next) { in igmpv3_del_delrec()
1115 if (pmc->multiaddr == multiaddr) in igmpv3_del_delrec()
1117 pmc_prev = pmc; in igmpv3_del_delrec()
1119 if (pmc) { in igmpv3_del_delrec()
1121 pmc_prev->next = pmc->next; in igmpv3_del_delrec()
1123 in_dev->mc_tomb = pmc->next; in igmpv3_del_delrec()
1126 if (pmc) { in igmpv3_del_delrec()
1127 for (psf = pmc->tomb; psf; psf = psf_next) { in igmpv3_del_delrec()
1131 in_dev_put(pmc->interface); in igmpv3_del_delrec()
1132 kfree(pmc); in igmpv3_del_delrec()
1138 struct ip_mc_list *pmc, *nextpmc; in igmpv3_clear_delrec() local
1141 pmc = in_dev->mc_tomb; in igmpv3_clear_delrec()
1145 for (; pmc; pmc = nextpmc) { in igmpv3_clear_delrec()
1146 nextpmc = pmc->next; in igmpv3_clear_delrec()
1147 ip_mc_clear_src(pmc); in igmpv3_clear_delrec()
1148 in_dev_put(pmc->interface); in igmpv3_clear_delrec()
1149 kfree(pmc); in igmpv3_clear_delrec()
1153 for_each_pmc_rcu(in_dev, pmc) { in igmpv3_clear_delrec()
1156 spin_lock_bh(&pmc->lock); in igmpv3_clear_delrec()
1157 psf = pmc->tomb; in igmpv3_clear_delrec()
1158 pmc->tomb = NULL; in igmpv3_clear_delrec()
1159 spin_unlock_bh(&pmc->lock); in igmpv3_clear_delrec()
1409 struct ip_mc_list *pmc; in ip_mc_unmap() local
1413 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_unmap()
1414 igmp_group_dropped(pmc); in ip_mc_unmap()
1419 struct ip_mc_list *pmc; in ip_mc_remap() local
1423 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_remap()
1424 igmp_group_added(pmc); in ip_mc_remap()
1431 struct ip_mc_list *pmc; in ip_mc_down() local
1435 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_down()
1436 igmp_group_dropped(pmc); in ip_mc_down()
1470 struct ip_mc_list *pmc; in ip_mc_up() local
1479 for_each_pmc_rtnl(in_dev, pmc) in ip_mc_up()
1480 igmp_group_added(pmc); in ip_mc_up()
1547 static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, in ip_mc_del1_src() argument
1554 for (psf = pmc->sources; psf; psf = psf->sf_next) { in ip_mc_del1_src()
1565 ip_rt_multicast_event(pmc->interface); in ip_mc_del1_src()
1569 struct in_device *in_dev = pmc->interface; in ip_mc_del1_src()
1576 pmc->sources = psf->sf_next; in ip_mc_del1_src()
1581 psf->sf_next = pmc->tomb; in ip_mc_del1_src()
1582 pmc->tomb = psf; in ip_mc_del1_src()
1598 struct ip_mc_list *pmc; in ip_mc_del_src() local
1605 for_each_pmc_rcu(in_dev, pmc) { in ip_mc_del_src()
1606 if (*pmca == pmc->multiaddr) in ip_mc_del_src()
1609 if (!pmc) { in ip_mc_del_src()
1614 spin_lock_bh(&pmc->lock); in ip_mc_del_src()
1617 sf_markstate(pmc); in ip_mc_del_src()
1621 if (!pmc->sfcount[sfmode]) in ip_mc_del_src()
1623 pmc->sfcount[sfmode]--; in ip_mc_del_src()
1627 int rv = ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); in ip_mc_del_src()
1633 if (pmc->sfmode == MCAST_EXCLUDE && in ip_mc_del_src()
1634 pmc->sfcount[MCAST_EXCLUDE] == 0 && in ip_mc_del_src()
1635 pmc->sfcount[MCAST_INCLUDE]) { in ip_mc_del_src()
1641 pmc->sfmode = MCAST_INCLUDE; in ip_mc_del_src()
1643 pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv; in ip_mc_del_src()
1644 in_dev->mr_ifc_count = pmc->crcount; in ip_mc_del_src()
1645 for (psf = pmc->sources; psf; psf = psf->sf_next) in ip_mc_del_src()
1647 igmp_ifc_event(pmc->interface); in ip_mc_del_src()
1648 } else if (sf_setstate(pmc) || changerec) { in ip_mc_del_src()
1649 igmp_ifc_event(pmc->interface); in ip_mc_del_src()
1653 spin_unlock_bh(&pmc->lock); in ip_mc_del_src()
1660 static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode, in ip_mc_add1_src() argument
1666 for (psf = pmc->sources; psf; psf = psf->sf_next) { in ip_mc_add1_src()
1679 pmc->sources = psf; in ip_mc_add1_src()
1683 ip_rt_multicast_event(pmc->interface); in ip_mc_add1_src()
1689 static void sf_markstate(struct ip_mc_list *pmc) in sf_markstate() argument
1692 int mca_xcount = pmc->sfcount[MCAST_EXCLUDE]; in sf_markstate()
1694 for (psf = pmc->sources; psf; psf = psf->sf_next) in sf_markstate()
1695 if (pmc->sfcount[MCAST_EXCLUDE]) { in sf_markstate()
1703 static int sf_setstate(struct ip_mc_list *pmc) in sf_setstate() argument
1706 int mca_xcount = pmc->sfcount[MCAST_EXCLUDE]; in sf_setstate()
1707 int qrv = pmc->interface->mr_qrv; in sf_setstate()
1711 for (psf = pmc->sources; psf; psf = psf->sf_next) { in sf_setstate()
1712 if (pmc->sfcount[MCAST_EXCLUDE]) { in sf_setstate()
1721 for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) { in sf_setstate()
1730 pmc->tomb = dpsf->sf_next; in sf_setstate()
1743 for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) in sf_setstate()
1752 dpsf->sf_next = pmc->tomb; in sf_setstate()
1753 pmc->tomb = dpsf; in sf_setstate()
1769 struct ip_mc_list *pmc; in ip_mc_add_src() local
1776 for_each_pmc_rcu(in_dev, pmc) { in ip_mc_add_src()
1777 if (*pmca == pmc->multiaddr) in ip_mc_add_src()
1780 if (!pmc) { in ip_mc_add_src()
1785 spin_lock_bh(&pmc->lock); in ip_mc_add_src()
1789 sf_markstate(pmc); in ip_mc_add_src()
1791 isexclude = pmc->sfmode == MCAST_EXCLUDE; in ip_mc_add_src()
1793 pmc->sfcount[sfmode]++; in ip_mc_add_src()
1796 err = ip_mc_add1_src(pmc, sfmode, &psfsrc[i]); in ip_mc_add_src()
1804 pmc->sfcount[sfmode]--; in ip_mc_add_src()
1806 (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]); in ip_mc_add_src()
1807 } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { in ip_mc_add_src()
1810 in_dev = pmc->interface; in ip_mc_add_src()
1814 if (pmc->sfcount[MCAST_EXCLUDE]) in ip_mc_add_src()
1815 pmc->sfmode = MCAST_EXCLUDE; in ip_mc_add_src()
1816 else if (pmc->sfcount[MCAST_INCLUDE]) in ip_mc_add_src()
1817 pmc->sfmode = MCAST_INCLUDE; in ip_mc_add_src()
1821 pmc->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv; in ip_mc_add_src()
1822 in_dev->mr_ifc_count = pmc->crcount; in ip_mc_add_src()
1823 for (psf = pmc->sources; psf; psf = psf->sf_next) in ip_mc_add_src()
1826 } else if (sf_setstate(pmc)) { in ip_mc_add_src()
1830 spin_unlock_bh(&pmc->lock); in ip_mc_add_src()
1834 static void ip_mc_clear_src(struct ip_mc_list *pmc) in ip_mc_clear_src() argument
1838 for (psf = pmc->tomb; psf; psf = nextpsf) { in ip_mc_clear_src()
1842 pmc->tomb = NULL; in ip_mc_clear_src()
1843 for (psf = pmc->sources; psf; psf = nextpsf) { in ip_mc_clear_src()
1847 pmc->sources = NULL; in ip_mc_clear_src()
1848 pmc->sfmode = MCAST_EXCLUDE; in ip_mc_clear_src()
1849 pmc->sfcount[MCAST_INCLUDE] = 0; in ip_mc_clear_src()
1850 pmc->sfcount[MCAST_EXCLUDE] = 1; in ip_mc_clear_src()
1979 struct ip_mc_socklist *pmc; in ip_mc_source() local
2003 for_each_pmc_rtnl(inet, pmc) { in ip_mc_source()
2004 if ((pmc->multi.imr_multiaddr.s_addr == in ip_mc_source()
2006 (pmc->multi.imr_ifindex == imr.imr_ifindex)) in ip_mc_source()
2009 if (!pmc) { /* must have a prior join */ in ip_mc_source()
2014 if (pmc->sflist) { in ip_mc_source()
2015 if (pmc->sfmode != omode) { in ip_mc_source()
2019 } else if (pmc->sfmode != omode) { in ip_mc_source()
2022 ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, pmc->sfmode, 0, in ip_mc_source()
2024 pmc->sfmode = omode; in ip_mc_source()
2027 psl = rtnl_dereference(pmc->sflist); in ip_mc_source()
2083 rcu_assign_pointer(pmc->sflist, newpsl); in ip_mc_source()
2114 struct ip_mc_socklist *pmc; in ip_mc_msfilter() local
2145 for_each_pmc_rtnl(inet, pmc) { in ip_mc_msfilter()
2146 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && in ip_mc_msfilter()
2147 pmc->multi.imr_ifindex == imr.imr_ifindex) in ip_mc_msfilter()
2150 if (!pmc) { /* must have a prior join */ in ip_mc_msfilter()
2175 psl = rtnl_dereference(pmc->sflist); in ip_mc_msfilter()
2177 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, in ip_mc_msfilter()
2183 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, in ip_mc_msfilter()
2185 rcu_assign_pointer(pmc->sflist, newpsl); in ip_mc_msfilter()
2186 pmc->sfmode = msf->imsf_fmode; in ip_mc_msfilter()
2200 struct ip_mc_socklist *pmc; in ip_mc_msfget() local
2222 for_each_pmc_rtnl(inet, pmc) { in ip_mc_msfget()
2223 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && in ip_mc_msfget()
2224 pmc->multi.imr_ifindex == imr.imr_ifindex) in ip_mc_msfget()
2227 if (!pmc) /* must have a prior join */ in ip_mc_msfget()
2229 msf->imsf_fmode = pmc->sfmode; in ip_mc_msfget()
2230 psl = rtnl_dereference(pmc->sflist); in ip_mc_msfget()
2260 struct ip_mc_socklist *pmc; in ip_mc_gsfget() local
2275 for_each_pmc_rtnl(inet, pmc) { in ip_mc_gsfget()
2276 if (pmc->multi.imr_multiaddr.s_addr == addr && in ip_mc_gsfget()
2277 pmc->multi.imr_ifindex == gsf->gf_interface) in ip_mc_gsfget()
2280 if (!pmc) /* must have a prior join */ in ip_mc_gsfget()
2282 gsf->gf_fmode = pmc->sfmode; in ip_mc_gsfget()
2283 psl = rtnl_dereference(pmc->sflist); in ip_mc_gsfget()
2314 struct ip_mc_socklist *pmc; in ip_mc_sf_allow() local
2324 for_each_pmc_rcu(inet, pmc) { in ip_mc_sf_allow()
2325 if (pmc->multi.imr_multiaddr.s_addr == loc_addr && in ip_mc_sf_allow()
2326 pmc->multi.imr_ifindex == dif) in ip_mc_sf_allow()
2330 if (!pmc) in ip_mc_sf_allow()
2332 psl = rcu_dereference(pmc->sflist); in ip_mc_sf_allow()
2333 ret = (pmc->sfmode == MCAST_EXCLUDE); in ip_mc_sf_allow()
2342 if (pmc->sfmode == MCAST_INCLUDE && i >= psl->sl_count) in ip_mc_sf_allow()
2344 if (pmc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) in ip_mc_sf_allow()