Lines Matching +full:multi +full:- +full:socket
1 // SPDX-License-Identifier: GPL-2.0-or-later
30 * Chih-Jen Chang : Tried to revise IGMP to Version 2
31 * Tsu-Sheng Tsao E-mail: chihjenc@scf.usc.edu and tsusheng@scf.usc.edu
33 * ipmulti-3.5 source code.
34 * Chih-Jen Chang : Added the igmp_get_mrouter_info and
35 * Tsu-Sheng Tsao igmp_set_mrouter_info to keep track of
37 * Chih-Jen Chang : Added the max_resp_time parameter to
38 * Tsu-Sheng Tsao igmp_heard_query(). Using this parameter
41 * Chih-Jen Chang : Added a timer to revert to IGMP V2 router
42 * Tsu-Sheng Tsao if the specified time expired.
53 * igmp_timer_expire if tm->running is
64 * Alexey Kuznetsov: Accordance to igmp-v2-06 draft.
76 #include <linux/socket.h>
108 /* Parameter names and values are taken from igmp-v2-06 draft */
123 (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 1 || \
125 ((in_dev)->mr_v1_seen && \
126 time_before(jiffies, (in_dev)->mr_v1_seen)))
128 (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), FORCE_IGMP_VERSION) == 2 || \
130 ((in_dev)->mr_v2_seen && \
131 time_before(jiffies, (in_dev)->mr_v2_seen)))
169 if (refcount_dec_and_test(&im->refcnt)) { in ip_ma_put()
170 in_dev_put(im->interface); in ip_ma_put()
176 for (pmc = rcu_dereference(in_dev->mc_list); \
178 pmc = rcu_dereference(pmc->next_rcu))
181 for (pmc = rtnl_dereference(in_dev->mc_list); \
183 pmc = rtnl_dereference(pmc->next_rcu))
190 next = psf->sf_next; in ip_sf_list_clear_all()
204 spin_lock_bh(&im->lock); in igmp_stop_timer()
205 if (del_timer(&im->timer)) in igmp_stop_timer()
206 refcount_dec(&im->refcnt); in igmp_stop_timer()
207 im->tm_running = 0; in igmp_stop_timer()
208 im->reporter = 0; in igmp_stop_timer()
209 im->unsolicit_count = 0; in igmp_stop_timer()
210 spin_unlock_bh(&im->lock); in igmp_stop_timer()
213 /* It must be called with locked im->lock */
218 im->tm_running = 1; in igmp_start_timer()
219 if (refcount_inc_not_zero(&im->refcnt)) { in igmp_start_timer()
220 if (mod_timer(&im->timer, jiffies + tv + 2)) in igmp_start_timer()
227 int tv = prandom_u32() % in_dev->mr_maxdelay; in igmp_gq_start_timer()
230 if (in_dev->mr_gq_running && in igmp_gq_start_timer()
231 time_after_eq(exp, (in_dev->mr_gq_timer).expires)) in igmp_gq_start_timer()
234 in_dev->mr_gq_running = 1; in igmp_gq_start_timer()
235 if (!mod_timer(&in_dev->mr_gq_timer, exp)) in igmp_gq_start_timer()
243 if (!mod_timer(&in_dev->mr_ifc_timer, jiffies+tv+2)) in igmp_ifc_start_timer()
249 spin_lock_bh(&im->lock); in igmp_mod_timer()
250 im->unsolicit_count = 0; in igmp_mod_timer()
251 if (del_timer(&im->timer)) { in igmp_mod_timer()
252 if ((long)(im->timer.expires-jiffies) < max_delay) { in igmp_mod_timer()
253 add_timer(&im->timer); in igmp_mod_timer()
254 im->tm_running = 1; in igmp_mod_timer()
255 spin_unlock_bh(&im->lock); in igmp_mod_timer()
258 refcount_dec(&im->refcnt); in igmp_mod_timer()
261 spin_unlock_bh(&im->lock); in igmp_mod_timer()
280 if (!(pmc->gsquery && !psf->sf_gsresp)) { in is_in()
281 if (pmc->sfmode == MCAST_INCLUDE) in is_in()
286 if (psf->sf_count[MCAST_INCLUDE]) in is_in()
288 return pmc->sfcount[MCAST_EXCLUDE] == in is_in()
289 psf->sf_count[MCAST_EXCLUDE]; in is_in()
295 return psf->sf_count[MCAST_INCLUDE] != 0; in is_in()
299 if (pmc->sfcount[MCAST_EXCLUDE] == 0 || in is_in()
300 psf->sf_count[MCAST_INCLUDE]) in is_in()
302 return pmc->sfcount[MCAST_EXCLUDE] == in is_in()
303 psf->sf_count[MCAST_EXCLUDE]; in is_in()
305 if (gdeleted || !psf->sf_crcount) in is_in()
307 return (pmc->sfmode == MCAST_INCLUDE) ^ sdeleted; in is_in()
309 if (pmc->sfmode == MCAST_INCLUDE) in is_in()
310 return gdeleted || (psf->sf_crcount && sdeleted); in is_in()
311 return psf->sf_crcount && !gdeleted && !sdeleted; in is_in()
322 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_scount()
341 if (fl4->saddr == ifa->ifa_local) in igmpv3_get_srcaddr()
342 return fl4->saddr; in igmpv3_get_srcaddr()
357 int tlen = dev->needed_tailroom; in igmpv3_newpack()
369 skb->priority = TC_PRIO_CONTROL; in igmpv3_newpack()
373 IPPROTO_IGMP, 0, dev->ifindex); in igmpv3_newpack()
379 skb_dst_set(skb, &rt->dst); in igmpv3_newpack()
380 skb->dev = dev; in igmpv3_newpack()
389 pip->version = 4; in igmpv3_newpack()
390 pip->ihl = (sizeof(struct iphdr)+4)>>2; in igmpv3_newpack()
391 pip->tos = 0xc0; in igmpv3_newpack()
392 pip->frag_off = htons(IP_DF); in igmpv3_newpack()
393 pip->ttl = 1; in igmpv3_newpack()
394 pip->daddr = fl4.daddr; in igmpv3_newpack()
397 pip->saddr = igmpv3_get_srcaddr(dev, &fl4); in igmpv3_newpack()
400 pip->protocol = IPPROTO_IGMP; in igmpv3_newpack()
401 pip->tot_len = 0; /* filled in later */ in igmpv3_newpack()
408 skb->transport_header = skb->network_header + sizeof(struct iphdr) + 4; in igmpv3_newpack()
411 pig->type = IGMPV3_HOST_MEMBERSHIP_REPORT; in igmpv3_newpack()
412 pig->resv1 = 0; in igmpv3_newpack()
413 pig->csum = 0; in igmpv3_newpack()
414 pig->resv2 = 0; in igmpv3_newpack()
415 pig->ngrec = 0; in igmpv3_newpack()
422 const int igmplen = skb_tail_pointer(skb) - skb_transport_header(skb); in igmpv3_sendpack()
424 pig->csum = ip_compute_csum(igmp_hdr(skb), igmplen); in igmpv3_sendpack()
426 return ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); in igmpv3_sendpack()
437 struct net_device *dev = pmc->interface->dev; in add_grhead()
447 pgr->grec_type = type; in add_grhead()
448 pgr->grec_auxwords = 0; in add_grhead()
449 pgr->grec_nsrcs = 0; in add_grhead()
450 pgr->grec_mca = pmc->multiaddr; in add_grhead()
452 pih->ngrec = htons(ntohs(pih->ngrec)+1); in add_grhead()
462 struct net_device *dev = pmc->interface->dev; in add_grec()
470 if (pmc->multiaddr == IGMP_ALL_HOSTS) in add_grec()
472 if (ipv4_is_local_multicast(pmc->multiaddr) && in add_grec()
473 !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) in add_grec()
476 mtu = READ_ONCE(dev->mtu); in add_grec()
487 psf_list = sdeleted ? &pmc->tomb : &pmc->sources; in add_grec()
496 if (pih && pih->ngrec && in add_grec()
508 psf_next = psf->sf_next; in add_grec()
515 /* Based on RFC3376 5.1. Should not send source-list change in add_grec()
518 if (((gdeleted && pmc->sfmode == MCAST_EXCLUDE) || in add_grec()
519 (!gdeleted && pmc->crcount)) && in add_grec()
521 type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount) in add_grec()
526 psf->sf_gsresp = 0; in add_grec()
533 pgr->grec_nsrcs = htons(scount); in add_grec()
547 *psrc = psf->sf_inaddr; in add_grec()
550 type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount) { in add_grec()
552 psf->sf_crcount--; in add_grec()
553 if ((sdeleted || gdeleted) && psf->sf_crcount == 0) { in add_grec()
555 psf_prev->sf_next = psf->sf_next; in add_grec()
557 *psf_list = psf->sf_next; in add_grec()
570 if (pmc->crcount || isquery) { in add_grec()
580 pgr->grec_nsrcs = htons(scount); in add_grec()
583 pmc->gsquery = 0; /* clear query state on report */ in add_grec()
590 struct net *net = dev_net(in_dev->dev); in igmpv3_send_report()
596 if (pmc->multiaddr == IGMP_ALL_HOSTS) in igmpv3_send_report()
598 if (ipv4_is_local_multicast(pmc->multiaddr) && in igmpv3_send_report()
599 !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) in igmpv3_send_report()
601 spin_lock_bh(&pmc->lock); in igmpv3_send_report()
602 if (pmc->sfcount[MCAST_EXCLUDE]) in igmpv3_send_report()
607 spin_unlock_bh(&pmc->lock); in igmpv3_send_report()
611 spin_lock_bh(&pmc->lock); in igmpv3_send_report()
612 if (pmc->sfcount[MCAST_EXCLUDE]) in igmpv3_send_report()
617 spin_unlock_bh(&pmc->lock); in igmpv3_send_report()
625 * remove zero-count source records from a source filter list
633 psf_next = psf->sf_next; in igmpv3_clear_zeros()
634 if (psf->sf_crcount == 0) { in igmpv3_clear_zeros()
636 psf_prev->sf_next = psf->sf_next; in igmpv3_clear_zeros()
638 *ppsf = psf->sf_next; in igmpv3_clear_zeros()
647 ip_sf_list_clear_all(pmc->sources); in kfree_pmc()
648 ip_sf_list_clear_all(pmc->tomb); in kfree_pmc()
659 spin_lock_bh(&in_dev->mc_tomb_lock); in igmpv3_send_cr()
663 for (pmc = in_dev->mc_tomb; pmc; pmc = pmc_next) { in igmpv3_send_cr()
664 pmc_next = pmc->next; in igmpv3_send_cr()
665 if (pmc->sfmode == MCAST_INCLUDE) { in igmpv3_send_cr()
671 if (pmc->crcount) { in igmpv3_send_cr()
672 if (pmc->sfmode == MCAST_EXCLUDE) { in igmpv3_send_cr()
676 pmc->crcount--; in igmpv3_send_cr()
677 if (pmc->crcount == 0) { in igmpv3_send_cr()
678 igmpv3_clear_zeros(&pmc->tomb); in igmpv3_send_cr()
679 igmpv3_clear_zeros(&pmc->sources); in igmpv3_send_cr()
682 if (pmc->crcount == 0 && !pmc->tomb && !pmc->sources) { in igmpv3_send_cr()
684 pmc_prev->next = pmc_next; in igmpv3_send_cr()
686 in_dev->mc_tomb = pmc_next; in igmpv3_send_cr()
687 in_dev_put(pmc->interface); in igmpv3_send_cr()
692 spin_unlock_bh(&in_dev->mc_tomb_lock); in igmpv3_send_cr()
696 spin_lock_bh(&pmc->lock); in igmpv3_send_cr()
697 if (pmc->sfcount[MCAST_EXCLUDE]) { in igmpv3_send_cr()
708 if (pmc->crcount) { in igmpv3_send_cr()
709 if (pmc->sfmode == MCAST_EXCLUDE) in igmpv3_send_cr()
714 pmc->crcount--; in igmpv3_send_cr()
716 spin_unlock_bh(&pmc->lock); in igmpv3_send_cr()
732 struct net_device *dev = in_dev->dev; in igmp_send_report()
734 __be32 group = pmc ? pmc->multiaddr : 0; in igmp_send_report()
743 !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) in igmp_send_report()
753 IPPROTO_IGMP, 0, dev->ifindex); in igmp_send_report()
755 return -1; in igmp_send_report()
758 tlen = dev->needed_tailroom; in igmp_send_report()
762 return -1; in igmp_send_report()
764 skb->priority = TC_PRIO_CONTROL; in igmp_send_report()
766 skb_dst_set(skb, &rt->dst); in igmp_send_report()
774 iph->version = 4; in igmp_send_report()
775 iph->ihl = (sizeof(struct iphdr)+4)>>2; in igmp_send_report()
776 iph->tos = 0xc0; in igmp_send_report()
777 iph->frag_off = htons(IP_DF); in igmp_send_report()
778 iph->ttl = 1; in igmp_send_report()
779 iph->daddr = dst; in igmp_send_report()
780 iph->saddr = fl4.saddr; in igmp_send_report()
781 iph->protocol = IPPROTO_IGMP; in igmp_send_report()
789 ih->type = type; in igmp_send_report()
790 ih->code = 0; in igmp_send_report()
791 ih->csum = 0; in igmp_send_report()
792 ih->group = group; in igmp_send_report()
793 ih->csum = ip_compute_csum((void *)ih, sizeof(struct igmphdr)); in igmp_send_report()
795 return ip_local_out(net, skb->sk, skb); in igmp_send_report()
802 in_dev->mr_gq_running = 0; in igmp_gq_timer_expire()
814 mr_ifc_count = READ_ONCE(in_dev->mr_ifc_count); in igmp_ifc_timer_expire()
817 if (cmpxchg(&in_dev->mr_ifc_count, in igmp_ifc_timer_expire()
819 mr_ifc_count - 1) != mr_ifc_count) in igmp_ifc_timer_expire()
829 struct net *net = dev_net(in_dev->dev); in igmp_ifc_event()
832 WRITE_ONCE(in_dev->mr_ifc_count, in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv)); in igmp_ifc_event()
840 struct in_device *in_dev = im->interface; in igmp_timer_expire()
842 spin_lock(&im->lock); in igmp_timer_expire()
843 im->tm_running = 0; in igmp_timer_expire()
845 if (im->unsolicit_count && --im->unsolicit_count) in igmp_timer_expire()
848 im->reporter = 1; in igmp_timer_expire()
849 spin_unlock(&im->lock); in igmp_timer_expire()
861 /* mark EXCLUDE-mode sources */
868 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_xmarksources()
873 if (psf->sf_count[MCAST_INCLUDE] || in igmp_xmarksources()
874 pmc->sfcount[MCAST_EXCLUDE] != in igmp_xmarksources()
875 psf->sf_count[MCAST_EXCLUDE]) in igmp_xmarksources()
877 if (srcs[i] == psf->sf_inaddr) { in igmp_xmarksources()
883 pmc->gsquery = 0; in igmp_xmarksources()
894 if (pmc->sfmode == MCAST_EXCLUDE) in igmp_marksources()
897 /* mark INCLUDE-mode sources */ in igmp_marksources()
899 for (psf = pmc->sources; psf; psf = psf->sf_next) { in igmp_marksources()
903 if (srcs[i] == psf->sf_inaddr) { in igmp_marksources()
904 psf->sf_gsresp = 1; in igmp_marksources()
910 pmc->gsquery = 0; in igmp_marksources()
913 pmc->gsquery = 1; in igmp_marksources()
921 struct net *net = dev_net(in_dev->dev); in igmp_heard_report()
923 /* Timers are only set for non-local groups */ in igmp_heard_report()
928 !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) in igmp_heard_report()
933 if (im->multiaddr == group) { in igmp_heard_report()
949 __be32 group = ih->group; in igmp_heard_query()
952 struct net *net = dev_net(in_dev->dev); in igmp_heard_query()
956 if (ih->code == 0) { in igmp_heard_query()
960 in_dev->mr_v1_seen = jiffies + in igmp_heard_query()
961 (in_dev->mr_qrv * in_dev->mr_qi) + in igmp_heard_query()
962 in_dev->mr_qri; in igmp_heard_query()
966 max_delay = ih->code*(HZ/IGMP_TIMER_SCALE); in igmp_heard_query()
967 in_dev->mr_v2_seen = jiffies + in igmp_heard_query()
968 (in_dev->mr_qrv * in_dev->mr_qi) + in igmp_heard_query()
969 in_dev->mr_qri; in igmp_heard_query()
972 WRITE_ONCE(in_dev->mr_ifc_count, 0); in igmp_heard_query()
973 if (del_timer(&in_dev->mr_ifc_timer)) in igmp_heard_query()
990 max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); in igmp_heard_query()
998 if (ih3->nsrcs) { in igmp_heard_query()
1000 + ntohs(ih3->nsrcs)*sizeof(__be32))) in igmp_heard_query()
1005 max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); in igmp_heard_query()
1008 in_dev->mr_maxdelay = max_delay; in igmp_heard_query()
1014 in_dev->mr_qrv = ih3->qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv); in igmp_heard_query()
1015 in_dev->mr_qi = IGMPV3_QQIC(ih3->qqic)*HZ ?: IGMP_QUERY_INTERVAL; in igmp_heard_query()
1021 if (in_dev->mr_qri >= in_dev->mr_qi) in igmp_heard_query()
1022 in_dev->mr_qri = (in_dev->mr_qi/HZ - 1)*HZ; in igmp_heard_query()
1025 if (ih3->nsrcs) in igmp_heard_query()
1030 /* mark sources to include, if group & source-specific */ in igmp_heard_query()
1031 mark = ih3->nsrcs != 0; in igmp_heard_query()
1035 * - Start the timers in all of our membership records in igmp_heard_query()
1039 * - For timers already running check if they need to in igmp_heard_query()
1041 * - Use the igmp->igmp_code field as the maximum in igmp_heard_query()
1048 if (group && group != im->multiaddr) in igmp_heard_query()
1050 if (im->multiaddr == IGMP_ALL_HOSTS) in igmp_heard_query()
1052 if (ipv4_is_local_multicast(im->multiaddr) && in igmp_heard_query()
1053 !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) in igmp_heard_query()
1055 spin_lock_bh(&im->lock); in igmp_heard_query()
1056 if (im->tm_running) in igmp_heard_query()
1057 im->gsquery = im->gsquery && mark; in igmp_heard_query()
1059 im->gsquery = mark; in igmp_heard_query()
1060 changed = !im->gsquery || in igmp_heard_query()
1061 igmp_marksources(im, ntohs(ih3->nsrcs), ih3->srcs); in igmp_heard_query()
1062 spin_unlock_bh(&im->lock); in igmp_heard_query()
1073 /* This basically follows the spec line by line -- see RFC1112 */ in igmp_rcv()
1075 struct net_device *dev = skb->dev; in igmp_rcv()
1077 int len = skb->len; in igmp_rcv()
1081 dev = dev_get_by_index_rcu(dev_net(dev), IPCB(skb)->iif); in igmp_rcv()
1097 switch (ih->type) { in igmp_rcv()
1107 if (skb->pkt_type == PACKET_MULTICAST || in igmp_rcv()
1108 skb->pkt_type == PACKET_BROADCAST) in igmp_rcv()
1109 dropped = igmp_heard_report(in_dev, ih->group); in igmp_rcv()
1144 struct net_device *dev = in_dev->dev; in ip_mc_filter_add()
1146 /* Checking for IFF_MULTICAST here is WRONG-WRONG-WRONG. in ip_mc_filter_add()
1150 if (dev->mc_list && dev->flags&IFF_MULTICAST) { do it; } in ip_mc_filter_add()
1151 --ANK in ip_mc_filter_add()
1164 struct net_device *dev = in_dev->dev; in ip_mc_filter_del()
1178 struct net *net = dev_net(in_dev->dev); in igmpv3_add_delrec()
1184 * non-deleted or query-response MCA's. in igmpv3_add_delrec()
1189 spin_lock_init(&pmc->lock); in igmpv3_add_delrec()
1190 spin_lock_bh(&im->lock); in igmpv3_add_delrec()
1191 pmc->interface = im->interface; in igmpv3_add_delrec()
1193 pmc->multiaddr = im->multiaddr; in igmpv3_add_delrec()
1194 pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv); in igmpv3_add_delrec()
1195 pmc->sfmode = im->sfmode; in igmpv3_add_delrec()
1196 if (pmc->sfmode == MCAST_INCLUDE) { in igmpv3_add_delrec()
1199 pmc->tomb = im->tomb; in igmpv3_add_delrec()
1200 pmc->sources = im->sources; in igmpv3_add_delrec()
1201 im->tomb = im->sources = NULL; in igmpv3_add_delrec()
1202 for (psf = pmc->sources; psf; psf = psf->sf_next) in igmpv3_add_delrec()
1203 psf->sf_crcount = pmc->crcount; in igmpv3_add_delrec()
1205 spin_unlock_bh(&im->lock); in igmpv3_add_delrec()
1207 spin_lock_bh(&in_dev->mc_tomb_lock); in igmpv3_add_delrec()
1208 pmc->next = in_dev->mc_tomb; in igmpv3_add_delrec()
1209 in_dev->mc_tomb = pmc; in igmpv3_add_delrec()
1210 spin_unlock_bh(&in_dev->mc_tomb_lock); in igmpv3_add_delrec()
1220 struct net *net = dev_net(in_dev->dev); in igmpv3_del_delrec()
1221 __be32 multiaddr = im->multiaddr; in igmpv3_del_delrec()
1223 spin_lock_bh(&in_dev->mc_tomb_lock); in igmpv3_del_delrec()
1225 for (pmc = in_dev->mc_tomb; pmc; pmc = pmc->next) { in igmpv3_del_delrec()
1226 if (pmc->multiaddr == multiaddr) in igmpv3_del_delrec()
1232 pmc_prev->next = pmc->next; in igmpv3_del_delrec()
1234 in_dev->mc_tomb = pmc->next; in igmpv3_del_delrec()
1236 spin_unlock_bh(&in_dev->mc_tomb_lock); in igmpv3_del_delrec()
1238 spin_lock_bh(&im->lock); in igmpv3_del_delrec()
1240 im->interface = pmc->interface; in igmpv3_del_delrec()
1241 if (im->sfmode == MCAST_INCLUDE) { in igmpv3_del_delrec()
1242 swap(im->tomb, pmc->tomb); in igmpv3_del_delrec()
1243 swap(im->sources, pmc->sources); in igmpv3_del_delrec()
1244 for (psf = im->sources; psf; psf = psf->sf_next) in igmpv3_del_delrec()
1245 psf->sf_crcount = in_dev->mr_qrv ?: in igmpv3_del_delrec()
1246 READ_ONCE(net->ipv4.sysctl_igmp_qrv); in igmpv3_del_delrec()
1248 im->crcount = in_dev->mr_qrv ?: in igmpv3_del_delrec()
1249 READ_ONCE(net->ipv4.sysctl_igmp_qrv); in igmpv3_del_delrec()
1251 in_dev_put(pmc->interface); in igmpv3_del_delrec()
1254 spin_unlock_bh(&im->lock); in igmpv3_del_delrec()
1264 spin_lock_bh(&in_dev->mc_tomb_lock); in igmpv3_clear_delrec()
1265 pmc = in_dev->mc_tomb; in igmpv3_clear_delrec()
1266 in_dev->mc_tomb = NULL; in igmpv3_clear_delrec()
1267 spin_unlock_bh(&in_dev->mc_tomb_lock); in igmpv3_clear_delrec()
1270 nextpmc = pmc->next; in igmpv3_clear_delrec()
1272 in_dev_put(pmc->interface); in igmpv3_clear_delrec()
1280 spin_lock_bh(&pmc->lock); in igmpv3_clear_delrec()
1281 psf = pmc->tomb; in igmpv3_clear_delrec()
1282 pmc->tomb = NULL; in igmpv3_clear_delrec()
1283 spin_unlock_bh(&pmc->lock); in igmpv3_clear_delrec()
1292 struct in_device *in_dev = im->interface; in __igmp_group_dropped()
1294 struct net *net = dev_net(in_dev->dev); in __igmp_group_dropped()
1298 if (im->loaded) { in __igmp_group_dropped()
1299 im->loaded = 0; in __igmp_group_dropped()
1300 ip_mc_filter_del(in_dev, im->multiaddr); in __igmp_group_dropped()
1304 if (im->multiaddr == IGMP_ALL_HOSTS) in __igmp_group_dropped()
1306 if (ipv4_is_local_multicast(im->multiaddr) && in __igmp_group_dropped()
1307 !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) in __igmp_group_dropped()
1310 reporter = im->reporter; in __igmp_group_dropped()
1313 if (!in_dev->dead) { in __igmp_group_dropped()
1336 struct in_device *in_dev = im->interface; in igmp_group_added()
1338 struct net *net = dev_net(in_dev->dev); in igmp_group_added()
1341 if (im->loaded == 0) { in igmp_group_added()
1342 im->loaded = 1; in igmp_group_added()
1343 ip_mc_filter_add(in_dev, im->multiaddr); in igmp_group_added()
1347 if (im->multiaddr == IGMP_ALL_HOSTS) in igmp_group_added()
1349 if (ipv4_is_local_multicast(im->multiaddr) && in igmp_group_added()
1350 !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) in igmp_group_added()
1353 if (in_dev->dead) in igmp_group_added()
1356 im->unsolicit_count = READ_ONCE(net->ipv4.sysctl_igmp_qrv); in igmp_group_added()
1358 spin_lock_bh(&im->lock); in igmp_group_added()
1360 spin_unlock_bh(&im->lock); in igmp_group_added()
1366 * not send filter-mode change record as the mode should be from in igmp_group_added()
1369 if (im->sfmode == MCAST_EXCLUDE) in igmp_group_added()
1370 im->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv); in igmp_group_added()
1383 return hash_32((__force u32)im->multiaddr, MC_HASH_SZ_LOG); in ip_mc_hash()
1392 mc_hash = rtnl_dereference(in_dev->mc_hash); in ip_mc_hash_add()
1395 im->next_hash = mc_hash[hash]; in ip_mc_hash_add()
1401 if (in_dev->mc_count < 4) in ip_mc_hash_add()
1411 im->next_hash = mc_hash[hash]; in ip_mc_hash_add()
1415 rcu_assign_pointer(in_dev->mc_hash, mc_hash); in ip_mc_hash_add()
1421 struct ip_mc_list __rcu **mc_hash = rtnl_dereference(in_dev->mc_hash); in ip_mc_hash_remove()
1428 mc_hash = &aux->next_hash; in ip_mc_hash_remove()
1429 *mc_hash = im->next_hash; in ip_mc_hash_remove()
1434 * A socket has joined a multicast group on device dev.
1444 if (im->multiaddr == addr) { in ____ip_mc_inc_group()
1445 im->users++; in ____ip_mc_inc_group()
1455 im->users = 1; in ____ip_mc_inc_group()
1456 im->interface = in_dev; in ____ip_mc_inc_group()
1458 im->multiaddr = addr; in ____ip_mc_inc_group()
1460 im->sfmode = mode; in ____ip_mc_inc_group()
1461 im->sfcount[mode] = 1; in ____ip_mc_inc_group()
1462 refcount_set(&im->refcnt, 1); in ____ip_mc_inc_group()
1463 spin_lock_init(&im->lock); in ____ip_mc_inc_group()
1465 timer_setup(&im->timer, igmp_timer_expire, 0); in ____ip_mc_inc_group()
1468 im->next_rcu = in_dev->mc_list; in ____ip_mc_inc_group()
1469 in_dev->mc_count++; in ____ip_mc_inc_group()
1470 rcu_assign_pointer(in_dev->mc_list, im); in ____ip_mc_inc_group()
1478 if (!in_dev->dead) in ____ip_mc_inc_group()
1503 return -EINVAL; in ip_mc_check_iphdr()
1507 if (iph->version != 4 || ip_hdrlen(skb) < sizeof(*iph)) in ip_mc_check_iphdr()
1508 return -EINVAL; in ip_mc_check_iphdr()
1510 offset += ip_hdrlen(skb) - sizeof(*iph); in ip_mc_check_iphdr()
1513 return -EINVAL; in ip_mc_check_iphdr()
1517 if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) in ip_mc_check_iphdr()
1518 return -EINVAL; in ip_mc_check_iphdr()
1520 len = skb_network_offset(skb) + ntohs(iph->tot_len); in ip_mc_check_iphdr()
1521 if (skb->len < len || len < offset) in ip_mc_check_iphdr()
1522 return -EINVAL; in ip_mc_check_iphdr()
1535 return ip_mc_may_pull(skb, len) ? 0 : -EINVAL; in ip_mc_check_igmp_reportv3()
1547 return -EINVAL; in ip_mc_check_igmp_query()
1551 return -EINVAL; in ip_mc_check_igmp_query()
1555 * all-systems destination addresses (224.0.0.1) for general queries in ip_mc_check_igmp_query()
1557 if (!igmp_hdr(skb)->group && in ip_mc_check_igmp_query()
1558 ip_hdr(skb)->daddr != htonl(INADDR_ALLHOSTS_GROUP)) in ip_mc_check_igmp_query()
1559 return -EINVAL; in ip_mc_check_igmp_query()
1566 switch (igmp_hdr(skb)->type) { in ip_mc_check_igmp_msg()
1576 return -ENOMSG; in ip_mc_check_igmp_msg()
1592 return -EINVAL; in ip_mc_check_igmp_csum()
1597 return -EINVAL; in ip_mc_check_igmp_csum()
1606 * ip_mc_check_igmp - checks whether this is a sane IGMP packet
1612 * -EINVAL: A broken packet was detected, i.e. it violates some internet
1614 * -ENOMSG: IP header validation succeeded but it is not an IGMP packet.
1615 * -ENOMEM: A memory allocation failure happened.
1627 if (ip_hdr(skb)->protocol != IPPROTO_IGMP) in ip_mc_check_igmp()
1628 return -ENOMSG; in ip_mc_check_igmp()
1646 struct net *net = dev_net(in_dev->dev); in ip_mc_rejoin_groups()
1651 if (im->multiaddr == IGMP_ALL_HOSTS) in ip_mc_rejoin_groups()
1653 if (ipv4_is_local_multicast(im->multiaddr) && in ip_mc_rejoin_groups()
1654 !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports)) in ip_mc_rejoin_groups()
1672 * A socket has left a multicast group on device dev
1682 for (ip = &in_dev->mc_list; in __ip_mc_dec_group()
1684 ip = &i->next_rcu) { in __ip_mc_dec_group()
1685 if (i->multiaddr == addr) { in __ip_mc_dec_group()
1686 if (--i->users == 0) { in __ip_mc_dec_group()
1688 *ip = i->next_rcu; in __ip_mc_dec_group()
1689 in_dev->mc_count--; in __ip_mc_dec_group()
1693 if (!in_dev->dead) in __ip_mc_dec_group()
1743 WRITE_ONCE(in_dev->mr_ifc_count, 0); in ip_mc_down()
1744 if (del_timer(&in_dev->mr_ifc_timer)) in ip_mc_down()
1746 in_dev->mr_gq_running = 0; in ip_mc_down()
1747 if (del_timer(&in_dev->mr_gq_timer)) in ip_mc_down()
1757 struct net *net = dev_net(in_dev->dev); in ip_mc_reset()
1759 in_dev->mr_qi = IGMP_QUERY_INTERVAL; in ip_mc_reset()
1760 in_dev->mr_qri = IGMP_QUERY_RESPONSE_INTERVAL; in ip_mc_reset()
1761 in_dev->mr_qrv = READ_ONCE(net->ipv4.sysctl_igmp_qrv); in ip_mc_reset()
1774 timer_setup(&in_dev->mr_gq_timer, igmp_gq_timer_expire, 0); in ip_mc_init_dev()
1775 timer_setup(&in_dev->mr_ifc_timer, igmp_ifc_timer_expire, 0); in ip_mc_init_dev()
1779 spin_lock_init(&in_dev->mc_tomb_lock); in ip_mc_init_dev()
1817 while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) { in ip_mc_destroy_dev()
1818 in_dev->mc_list = i->next_rcu; in ip_mc_destroy_dev()
1819 in_dev->mc_count--; in ip_mc_destroy_dev()
1831 if (imr->imr_ifindex) { in ip_mc_find_dev()
1832 idev = inetdev_by_index(net, imr->imr_ifindex); in ip_mc_find_dev()
1835 if (imr->imr_address.s_addr) { in ip_mc_find_dev()
1836 dev = __ip_dev_find(net, imr->imr_address.s_addr, false); in ip_mc_find_dev()
1843 imr->imr_multiaddr.s_addr, in ip_mc_find_dev()
1846 dev = rt->dst.dev; in ip_mc_find_dev()
1851 imr->imr_ifindex = dev->ifindex; in ip_mc_find_dev()
1858 * Join a socket to a group
1868 for (psf = pmc->sources; psf; psf = psf->sf_next) { in ip_mc_del1_src()
1869 if (psf->sf_inaddr == *psfsrc) in ip_mc_del1_src()
1873 if (!psf || psf->sf_count[sfmode] == 0) { in ip_mc_del1_src()
1875 return -ESRCH; in ip_mc_del1_src()
1877 psf->sf_count[sfmode]--; in ip_mc_del1_src()
1878 if (psf->sf_count[sfmode] == 0) { in ip_mc_del1_src()
1879 ip_rt_multicast_event(pmc->interface); in ip_mc_del1_src()
1881 if (!psf->sf_count[MCAST_INCLUDE] && !psf->sf_count[MCAST_EXCLUDE]) { in ip_mc_del1_src()
1883 struct in_device *in_dev = pmc->interface; in ip_mc_del1_src()
1884 struct net *net = dev_net(in_dev->dev); in ip_mc_del1_src()
1889 psf_prev->sf_next = psf->sf_next; in ip_mc_del1_src()
1891 pmc->sources = psf->sf_next; in ip_mc_del1_src()
1893 if (psf->sf_oldin && in ip_mc_del1_src()
1895 psf->sf_crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv); in ip_mc_del1_src()
1896 psf->sf_next = pmc->tomb; in ip_mc_del1_src()
1897 pmc->tomb = psf; in ip_mc_del1_src()
1918 return -ENODEV; in ip_mc_del_src()
1921 if (*pmca == pmc->multiaddr) in ip_mc_del_src()
1927 return -ESRCH; in ip_mc_del_src()
1929 spin_lock_bh(&pmc->lock); in ip_mc_del_src()
1935 err = -EINVAL; in ip_mc_del_src()
1936 if (!pmc->sfcount[sfmode]) in ip_mc_del_src()
1938 pmc->sfcount[sfmode]--; in ip_mc_del_src()
1948 if (pmc->sfmode == MCAST_EXCLUDE && in ip_mc_del_src()
1949 pmc->sfcount[MCAST_EXCLUDE] == 0 && in ip_mc_del_src()
1950 pmc->sfcount[MCAST_INCLUDE]) { in ip_mc_del_src()
1953 struct net *net = dev_net(in_dev->dev); in ip_mc_del_src()
1957 pmc->sfmode = MCAST_INCLUDE; in ip_mc_del_src()
1959 pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv); in ip_mc_del_src()
1960 WRITE_ONCE(in_dev->mr_ifc_count, pmc->crcount); in ip_mc_del_src()
1961 for (psf = pmc->sources; psf; psf = psf->sf_next) in ip_mc_del_src()
1962 psf->sf_crcount = 0; in ip_mc_del_src()
1963 igmp_ifc_event(pmc->interface); in ip_mc_del_src()
1965 igmp_ifc_event(pmc->interface); in ip_mc_del_src()
1969 spin_unlock_bh(&pmc->lock); in ip_mc_del_src()
1974 * Add multicast single-source filter to the interface list
1982 for (psf = pmc->sources; psf; psf = psf->sf_next) { in ip_mc_add1_src()
1983 if (psf->sf_inaddr == *psfsrc) in ip_mc_add1_src()
1990 return -ENOBUFS; in ip_mc_add1_src()
1991 psf->sf_inaddr = *psfsrc; in ip_mc_add1_src()
1993 psf_prev->sf_next = psf; in ip_mc_add1_src()
1995 pmc->sources = psf; in ip_mc_add1_src()
1997 psf->sf_count[sfmode]++; in ip_mc_add1_src()
1998 if (psf->sf_count[sfmode] == 1) { in ip_mc_add1_src()
1999 ip_rt_multicast_event(pmc->interface); in ip_mc_add1_src()
2008 int mca_xcount = pmc->sfcount[MCAST_EXCLUDE]; in sf_markstate()
2010 for (psf = pmc->sources; psf; psf = psf->sf_next) in sf_markstate()
2011 if (pmc->sfcount[MCAST_EXCLUDE]) { in sf_markstate()
2012 psf->sf_oldin = mca_xcount == in sf_markstate()
2013 psf->sf_count[MCAST_EXCLUDE] && in sf_markstate()
2014 !psf->sf_count[MCAST_INCLUDE]; in sf_markstate()
2016 psf->sf_oldin = psf->sf_count[MCAST_INCLUDE] != 0; in sf_markstate()
2022 int mca_xcount = pmc->sfcount[MCAST_EXCLUDE]; in sf_setstate()
2023 int qrv = pmc->interface->mr_qrv; in sf_setstate()
2027 for (psf = pmc->sources; psf; psf = psf->sf_next) { in sf_setstate()
2028 if (pmc->sfcount[MCAST_EXCLUDE]) { in sf_setstate()
2029 new_in = mca_xcount == psf->sf_count[MCAST_EXCLUDE] && in sf_setstate()
2030 !psf->sf_count[MCAST_INCLUDE]; in sf_setstate()
2032 new_in = psf->sf_count[MCAST_INCLUDE] != 0; in sf_setstate()
2034 if (!psf->sf_oldin) { in sf_setstate()
2037 for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) { in sf_setstate()
2038 if (dpsf->sf_inaddr == psf->sf_inaddr) in sf_setstate()
2044 prev->sf_next = dpsf->sf_next; in sf_setstate()
2046 pmc->tomb = dpsf->sf_next; in sf_setstate()
2049 psf->sf_crcount = qrv; in sf_setstate()
2052 } else if (psf->sf_oldin) { in sf_setstate()
2054 psf->sf_crcount = 0; in sf_setstate()
2059 for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) in sf_setstate()
2060 if (dpsf->sf_inaddr == psf->sf_inaddr) in sf_setstate()
2067 /* pmc->lock held by callers */ in sf_setstate()
2068 dpsf->sf_next = pmc->tomb; in sf_setstate()
2069 pmc->tomb = dpsf; in sf_setstate()
2071 dpsf->sf_crcount = qrv; in sf_setstate()
2090 return -ENODEV; in ip_mc_add_src()
2093 if (*pmca == pmc->multiaddr) in ip_mc_add_src()
2099 return -ESRCH; in ip_mc_add_src()
2101 spin_lock_bh(&pmc->lock); in ip_mc_add_src()
2107 isexclude = pmc->sfmode == MCAST_EXCLUDE; in ip_mc_add_src()
2109 pmc->sfcount[sfmode]++; in ip_mc_add_src()
2120 pmc->sfcount[sfmode]--; in ip_mc_add_src()
2123 } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { in ip_mc_add_src()
2126 struct net *net = dev_net(pmc->interface->dev); in ip_mc_add_src()
2127 in_dev = pmc->interface; in ip_mc_add_src()
2131 if (pmc->sfcount[MCAST_EXCLUDE]) in ip_mc_add_src()
2132 pmc->sfmode = MCAST_EXCLUDE; in ip_mc_add_src()
2133 else if (pmc->sfcount[MCAST_INCLUDE]) in ip_mc_add_src()
2134 pmc->sfmode = MCAST_INCLUDE; in ip_mc_add_src()
2138 pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv); in ip_mc_add_src()
2139 WRITE_ONCE(in_dev->mr_ifc_count, pmc->crcount); in ip_mc_add_src()
2140 for (psf = pmc->sources; psf; psf = psf->sf_next) in ip_mc_add_src()
2141 psf->sf_crcount = 0; in ip_mc_add_src()
2147 spin_unlock_bh(&pmc->lock); in ip_mc_add_src()
2155 spin_lock_bh(&pmc->lock); in ip_mc_clear_src()
2156 tomb = pmc->tomb; in ip_mc_clear_src()
2157 pmc->tomb = NULL; in ip_mc_clear_src()
2158 sources = pmc->sources; in ip_mc_clear_src()
2159 pmc->sources = NULL; in ip_mc_clear_src()
2160 pmc->sfmode = MCAST_EXCLUDE; in ip_mc_clear_src()
2161 pmc->sfcount[MCAST_INCLUDE] = 0; in ip_mc_clear_src()
2162 pmc->sfcount[MCAST_EXCLUDE] = 1; in ip_mc_clear_src()
2163 spin_unlock_bh(&pmc->lock); in ip_mc_clear_src()
2174 __be32 addr = imr->imr_multiaddr.s_addr; in __ip_mc_join_group()
2186 return -EINVAL; in __ip_mc_join_group()
2191 err = -ENODEV; in __ip_mc_join_group()
2195 err = -EADDRINUSE; in __ip_mc_join_group()
2196 ifindex = imr->imr_ifindex; in __ip_mc_join_group()
2198 if (i->multi.imr_multiaddr.s_addr == addr && in __ip_mc_join_group()
2199 i->multi.imr_ifindex == ifindex) in __ip_mc_join_group()
2203 err = -ENOBUFS; in __ip_mc_join_group()
2204 if (count >= READ_ONCE(net->ipv4.sysctl_igmp_max_memberships)) in __ip_mc_join_group()
2210 memcpy(&iml->multi, imr, sizeof(*imr)); in __ip_mc_join_group()
2211 iml->next_rcu = inet->mc_list; in __ip_mc_join_group()
2212 iml->sflist = NULL; in __ip_mc_join_group()
2213 iml->sfmode = mode; in __ip_mc_join_group()
2214 rcu_assign_pointer(inet->mc_list, iml); in __ip_mc_join_group()
2221 /* Join ASM (Any-Source Multicast) group
2229 /* Join SSM (Source-Specific Multicast) group
2240 struct ip_sf_socklist *psf = rtnl_dereference(iml->sflist); in ip_mc_leave_src()
2244 /* any-source empty exclude case */ in ip_mc_leave_src()
2245 return ip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr, in ip_mc_leave_src()
2246 iml->sfmode, 0, NULL, 0); in ip_mc_leave_src()
2248 err = ip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr, in ip_mc_leave_src()
2249 iml->sfmode, psf->sl_count, psf->sl_addr, 0); in ip_mc_leave_src()
2250 RCU_INIT_POINTER(iml->sflist, NULL); in ip_mc_leave_src()
2252 atomic_sub(IP_SFLSIZE(psf->sl_max), &sk->sk_omem_alloc); in ip_mc_leave_src()
2264 __be32 group = imr->imr_multiaddr.s_addr; in ip_mc_leave_group()
2266 int ret = -EADDRNOTAVAIL; in ip_mc_leave_group()
2271 if (!imr->imr_ifindex && !imr->imr_address.s_addr && !in_dev) { in ip_mc_leave_group()
2272 ret = -ENODEV; in ip_mc_leave_group()
2275 ifindex = imr->imr_ifindex; in ip_mc_leave_group()
2276 for (imlp = &inet->mc_list; in ip_mc_leave_group()
2278 imlp = &iml->next_rcu) { in ip_mc_leave_group()
2279 if (iml->multi.imr_multiaddr.s_addr != group) in ip_mc_leave_group()
2282 if (iml->multi.imr_ifindex != ifindex) in ip_mc_leave_group()
2284 } else if (imr->imr_address.s_addr && imr->imr_address.s_addr != in ip_mc_leave_group()
2285 iml->multi.imr_address.s_addr) in ip_mc_leave_group()
2290 *imlp = iml->next_rcu; in ip_mc_leave_group()
2296 atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); in ip_mc_leave_group()
2310 __be32 addr = mreqs->imr_multiaddr; in ip_mc_source()
2320 return -EINVAL; in ip_mc_source()
2324 imr.imr_multiaddr.s_addr = mreqs->imr_multiaddr; in ip_mc_source()
2325 imr.imr_address.s_addr = mreqs->imr_interface; in ip_mc_source()
2330 err = -ENODEV; in ip_mc_source()
2333 err = -EADDRNOTAVAIL; in ip_mc_source()
2336 if ((pmc->multi.imr_multiaddr.s_addr == in ip_mc_source()
2338 (pmc->multi.imr_ifindex == imr.imr_ifindex)) in ip_mc_source()
2342 err = -EINVAL; in ip_mc_source()
2346 if (pmc->sflist) { in ip_mc_source()
2347 if (pmc->sfmode != omode) { in ip_mc_source()
2348 err = -EINVAL; in ip_mc_source()
2351 } else if (pmc->sfmode != omode) { in ip_mc_source()
2352 /* allow mode switches for empty-set filters */ in ip_mc_source()
2353 ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 0, NULL, 0); in ip_mc_source()
2354 ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, pmc->sfmode, 0, in ip_mc_source()
2356 pmc->sfmode = omode; in ip_mc_source()
2359 psl = rtnl_dereference(pmc->sflist); in ip_mc_source()
2362 goto done; /* err = -EADDRNOTAVAIL */ in ip_mc_source()
2364 for (i = 0; i < psl->sl_count; i++) { in ip_mc_source()
2365 rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr, in ip_mc_source()
2371 goto done; /* err = -EADDRNOTAVAIL */ in ip_mc_source()
2373 /* special case - (INCLUDE, empty) == LEAVE_GROUP */ in ip_mc_source()
2374 if (psl->sl_count == 1 && omode == MCAST_INCLUDE) { in ip_mc_source()
2380 ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1, in ip_mc_source()
2381 &mreqs->imr_sourceaddr, 1); in ip_mc_source()
2383 for (j = i+1; j < psl->sl_count; j++) in ip_mc_source()
2384 psl->sl_addr[j-1] = psl->sl_addr[j]; in ip_mc_source()
2385 psl->sl_count--; in ip_mc_source()
2391 if (psl && psl->sl_count >= READ_ONCE(net->ipv4.sysctl_igmp_max_msf)) { in ip_mc_source()
2392 err = -ENOBUFS; in ip_mc_source()
2395 if (!psl || psl->sl_count == psl->sl_max) { in ip_mc_source()
2400 count += psl->sl_max; in ip_mc_source()
2403 err = -ENOBUFS; in ip_mc_source()
2406 newpsl->sl_max = count; in ip_mc_source()
2407 newpsl->sl_count = count - IP_SFBLOCK; in ip_mc_source()
2409 for (i = 0; i < psl->sl_count; i++) in ip_mc_source()
2410 newpsl->sl_addr[i] = psl->sl_addr[i]; in ip_mc_source()
2412 atomic_sub(IP_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc); in ip_mc_source()
2414 rcu_assign_pointer(pmc->sflist, newpsl); in ip_mc_source()
2420 for (i = 0; i < psl->sl_count; i++) { in ip_mc_source()
2421 rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr, in ip_mc_source()
2428 for (j = psl->sl_count-1; j >= i; j--) in ip_mc_source()
2429 psl->sl_addr[j+1] = psl->sl_addr[j]; in ip_mc_source()
2430 psl->sl_addr[i] = mreqs->imr_sourceaddr; in ip_mc_source()
2431 psl->sl_count++; in ip_mc_source()
2434 ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1, in ip_mc_source()
2435 &mreqs->imr_sourceaddr, 1); in ip_mc_source()
2446 __be32 addr = msf->imsf_multiaddr; in ip_mc_msfilter()
2455 return -EINVAL; in ip_mc_msfilter()
2456 if (msf->imsf_fmode != MCAST_INCLUDE && in ip_mc_msfilter()
2457 msf->imsf_fmode != MCAST_EXCLUDE) in ip_mc_msfilter()
2458 return -EINVAL; in ip_mc_msfilter()
2462 imr.imr_multiaddr.s_addr = msf->imsf_multiaddr; in ip_mc_msfilter()
2463 imr.imr_address.s_addr = msf->imsf_interface; in ip_mc_msfilter()
2468 err = -ENODEV; in ip_mc_msfilter()
2472 /* special case - (INCLUDE, empty) == LEAVE_GROUP */ in ip_mc_msfilter()
2473 if (msf->imsf_fmode == MCAST_INCLUDE && msf->imsf_numsrc == 0) { in ip_mc_msfilter()
2479 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && in ip_mc_msfilter()
2480 pmc->multi.imr_ifindex == imr.imr_ifindex) in ip_mc_msfilter()
2484 err = -EINVAL; in ip_mc_msfilter()
2487 if (msf->imsf_numsrc) { in ip_mc_msfilter()
2488 newpsl = sock_kmalloc(sk, IP_SFLSIZE(msf->imsf_numsrc), in ip_mc_msfilter()
2491 err = -ENOBUFS; in ip_mc_msfilter()
2494 newpsl->sl_max = newpsl->sl_count = msf->imsf_numsrc; in ip_mc_msfilter()
2495 memcpy(newpsl->sl_addr, msf->imsf_slist, in ip_mc_msfilter()
2496 msf->imsf_numsrc * sizeof(msf->imsf_slist[0])); in ip_mc_msfilter()
2497 err = ip_mc_add_src(in_dev, &msf->imsf_multiaddr, in ip_mc_msfilter()
2498 msf->imsf_fmode, newpsl->sl_count, newpsl->sl_addr, 0); in ip_mc_msfilter()
2500 sock_kfree_s(sk, newpsl, IP_SFLSIZE(newpsl->sl_max)); in ip_mc_msfilter()
2505 (void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr, in ip_mc_msfilter()
2506 msf->imsf_fmode, 0, NULL, 0); in ip_mc_msfilter()
2508 psl = rtnl_dereference(pmc->sflist); in ip_mc_msfilter()
2510 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, in ip_mc_msfilter()
2511 psl->sl_count, psl->sl_addr, 0); in ip_mc_msfilter()
2513 atomic_sub(IP_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc); in ip_mc_msfilter()
2515 (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, in ip_mc_msfilter()
2518 rcu_assign_pointer(pmc->sflist, newpsl); in ip_mc_msfilter()
2521 pmc->sfmode = msf->imsf_fmode; in ip_mc_msfilter()
2534 __be32 addr = msf->imsf_multiaddr; in ip_mc_msfget()
2544 return -EINVAL; in ip_mc_msfget()
2546 imr.imr_multiaddr.s_addr = msf->imsf_multiaddr; in ip_mc_msfget()
2547 imr.imr_address.s_addr = msf->imsf_interface; in ip_mc_msfget()
2552 err = -ENODEV; in ip_mc_msfget()
2555 err = -EADDRNOTAVAIL; in ip_mc_msfget()
2558 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && in ip_mc_msfget()
2559 pmc->multi.imr_ifindex == imr.imr_ifindex) in ip_mc_msfget()
2564 msf->imsf_fmode = pmc->sfmode; in ip_mc_msfget()
2565 psl = rtnl_dereference(pmc->sflist); in ip_mc_msfget()
2570 count = psl->sl_count; in ip_mc_msfget()
2572 copycount = count < msf->imsf_numsrc ? count : msf->imsf_numsrc; in ip_mc_msfget()
2573 len = copycount * sizeof(psl->sl_addr[0]); in ip_mc_msfget()
2574 msf->imsf_numsrc = count; in ip_mc_msfget()
2577 return -EFAULT; in ip_mc_msfget()
2580 copy_to_user(&optval->imsf_slist[0], psl->sl_addr, len)) in ip_mc_msfget()
2581 return -EFAULT; in ip_mc_msfget()
2599 psin = (struct sockaddr_in *)&gsf->gf_group; in ip_mc_gsfget()
2600 if (psin->sin_family != AF_INET) in ip_mc_gsfget()
2601 return -EINVAL; in ip_mc_gsfget()
2602 addr = psin->sin_addr.s_addr; in ip_mc_gsfget()
2604 return -EINVAL; in ip_mc_gsfget()
2607 if (pmc->multi.imr_multiaddr.s_addr == addr && in ip_mc_gsfget()
2608 pmc->multi.imr_ifindex == gsf->gf_interface) in ip_mc_gsfget()
2612 return -EADDRNOTAVAIL; in ip_mc_gsfget()
2613 gsf->gf_fmode = pmc->sfmode; in ip_mc_gsfget()
2614 psl = rtnl_dereference(pmc->sflist); in ip_mc_gsfget()
2615 count = psl ? psl->sl_count : 0; in ip_mc_gsfget()
2616 copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc; in ip_mc_gsfget()
2617 gsf->gf_numsrc = count; in ip_mc_gsfget()
2623 psin->sin_family = AF_INET; in ip_mc_gsfget()
2624 psin->sin_addr.s_addr = psl->sl_addr[i]; in ip_mc_gsfget()
2626 return -EFAULT; in ip_mc_gsfget()
2649 if (pmc->multi.imr_multiaddr.s_addr == loc_addr && in ip_mc_sf_allow()
2650 (pmc->multi.imr_ifindex == dif || in ip_mc_sf_allow()
2651 (sdif && pmc->multi.imr_ifindex == sdif))) in ip_mc_sf_allow()
2654 ret = inet->mc_all; in ip_mc_sf_allow()
2657 psl = rcu_dereference(pmc->sflist); in ip_mc_sf_allow()
2658 ret = (pmc->sfmode == MCAST_EXCLUDE); in ip_mc_sf_allow()
2662 for (i = 0; i < psl->sl_count; i++) { in ip_mc_sf_allow()
2663 if (psl->sl_addr[i] == rmt_addr) in ip_mc_sf_allow()
2667 if (pmc->sfmode == MCAST_INCLUDE && i >= psl->sl_count) in ip_mc_sf_allow()
2669 if (pmc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) in ip_mc_sf_allow()
2679 * A socket is closing.
2688 if (!inet->mc_list) in ip_mc_drop_socket()
2692 while ((iml = rtnl_dereference(inet->mc_list)) != NULL) { in ip_mc_drop_socket()
2695 inet->mc_list = iml->next_rcu; in ip_mc_drop_socket()
2696 in_dev = inetdev_by_index(net, iml->multi.imr_ifindex); in ip_mc_drop_socket()
2699 ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); in ip_mc_drop_socket()
2701 atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); in ip_mc_drop_socket()
2715 mc_hash = rcu_dereference(in_dev->mc_hash); in ip_check_mc_rcu()
2721 im = rcu_dereference(im->next_hash)) { in ip_check_mc_rcu()
2722 if (im->multiaddr == mc_addr) in ip_check_mc_rcu()
2727 if (im->multiaddr == mc_addr) in ip_check_mc_rcu()
2735 spin_lock_bh(&im->lock); in ip_check_mc_rcu()
2736 for (psf = im->sources; psf; psf = psf->sf_next) { in ip_check_mc_rcu()
2737 if (psf->sf_inaddr == src_addr) in ip_check_mc_rcu()
2741 rv = psf->sf_count[MCAST_INCLUDE] || in ip_check_mc_rcu()
2742 psf->sf_count[MCAST_EXCLUDE] != in ip_check_mc_rcu()
2743 im->sfcount[MCAST_EXCLUDE]; in ip_check_mc_rcu()
2745 rv = im->sfcount[MCAST_EXCLUDE] != 0; in ip_check_mc_rcu()
2746 spin_unlock_bh(&im->lock); in ip_check_mc_rcu()
2760 #define igmp_mc_seq_private(seq) ((struct igmp_mc_iter_state *)(seq)->private)
2768 state->in_dev = NULL; in igmp_mc_get_first()
2769 for_each_netdev_rcu(net, state->dev) { in igmp_mc_get_first()
2772 in_dev = __in_dev_get_rcu(state->dev); in igmp_mc_get_first()
2775 im = rcu_dereference(in_dev->mc_list); in igmp_mc_get_first()
2777 state->in_dev = in_dev; in igmp_mc_get_first()
2788 im = rcu_dereference(im->next_rcu); in igmp_mc_get_next()
2790 state->dev = next_net_device_rcu(state->dev); in igmp_mc_get_next()
2791 if (!state->dev) { in igmp_mc_get_next()
2792 state->in_dev = NULL; in igmp_mc_get_next()
2795 state->in_dev = __in_dev_get_rcu(state->dev); in igmp_mc_get_next()
2796 if (!state->in_dev) in igmp_mc_get_next()
2798 im = rcu_dereference(state->in_dev->mc_list); in igmp_mc_get_next()
2808 --pos; in igmp_mc_get_idx()
2816 return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; in igmp_mc_seq_start()
2835 state->in_dev = NULL; in igmp_mc_seq_stop()
2836 state->dev = NULL; in igmp_mc_seq_stop()
2852 querier = IGMP_V1_SEEN(state->in_dev) ? "V1" : in igmp_mc_seq_show()
2853 IGMP_V2_SEEN(state->in_dev) ? "V2" : in igmp_mc_seq_show()
2859 if (rcu_access_pointer(state->in_dev->mc_list) == im) { in igmp_mc_seq_show()
2860 seq_printf(seq, "%d\t%-10s: %5d %7s\n", in igmp_mc_seq_show()
2861 state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier); in igmp_mc_seq_show()
2864 delta = im->timer.expires - jiffies; in igmp_mc_seq_show()
2867 im->multiaddr, im->users, in igmp_mc_seq_show()
2868 im->tm_running, in igmp_mc_seq_show()
2869 im->tm_running ? jiffies_delta_to_clock_t(delta) : 0, in igmp_mc_seq_show()
2870 im->reporter); in igmp_mc_seq_show()
2889 #define igmp_mcf_seq_private(seq) ((struct igmp_mcf_iter_state *)(seq)->private)
2898 state->idev = NULL; in igmp_mcf_get_first()
2899 state->im = NULL; in igmp_mcf_get_first()
2900 for_each_netdev_rcu(net, state->dev) { in igmp_mcf_get_first()
2902 idev = __in_dev_get_rcu(state->dev); in igmp_mcf_get_first()
2905 im = rcu_dereference(idev->mc_list); in igmp_mcf_get_first()
2907 spin_lock_bh(&im->lock); in igmp_mcf_get_first()
2908 psf = im->sources; in igmp_mcf_get_first()
2910 state->im = im; in igmp_mcf_get_first()
2911 state->idev = idev; in igmp_mcf_get_first()
2914 spin_unlock_bh(&im->lock); in igmp_mcf_get_first()
2924 psf = psf->sf_next; in igmp_mcf_get_next()
2926 spin_unlock_bh(&state->im->lock); in igmp_mcf_get_next()
2927 state->im = state->im->next; in igmp_mcf_get_next()
2928 while (!state->im) { in igmp_mcf_get_next()
2929 state->dev = next_net_device_rcu(state->dev); in igmp_mcf_get_next()
2930 if (!state->dev) { in igmp_mcf_get_next()
2931 state->idev = NULL; in igmp_mcf_get_next()
2934 state->idev = __in_dev_get_rcu(state->dev); in igmp_mcf_get_next()
2935 if (!state->idev) in igmp_mcf_get_next()
2937 state->im = rcu_dereference(state->idev->mc_list); in igmp_mcf_get_next()
2939 if (!state->im) in igmp_mcf_get_next()
2941 spin_lock_bh(&state->im->lock); in igmp_mcf_get_next()
2942 psf = state->im->sources; in igmp_mcf_get_next()
2953 --pos; in igmp_mcf_get_idx()
2961 return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; in igmp_mcf_seq_start()
2979 if (likely(state->im)) { in igmp_mcf_seq_stop()
2980 spin_unlock_bh(&state->im->lock); in igmp_mcf_seq_stop()
2981 state->im = NULL; in igmp_mcf_seq_stop()
2983 state->idev = NULL; in igmp_mcf_seq_stop()
2984 state->dev = NULL; in igmp_mcf_seq_stop()
2999 state->dev->ifindex, state->dev->name, in igmp_mcf_seq_show()
3000 ntohl(state->im->multiaddr), in igmp_mcf_seq_show()
3001 ntohl(psf->sf_inaddr), in igmp_mcf_seq_show()
3002 psf->sf_count[MCAST_INCLUDE], in igmp_mcf_seq_show()
3003 psf->sf_count[MCAST_EXCLUDE]); in igmp_mcf_seq_show()
3020 pde = proc_create_net("igmp", 0444, net->proc_net, &igmp_mc_seq_ops, in igmp_net_init()
3024 pde = proc_create_net("mcfilter", 0444, net->proc_net, in igmp_net_init()
3028 err = inet_ctl_sock_create(&net->ipv4.mc_autojoin_sk, AF_INET, in igmp_net_init()
3031 pr_err("Failed to initialize the IGMP autojoin socket (err %d)\n", in igmp_net_init()
3039 remove_proc_entry("mcfilter", net->proc_net); in igmp_net_init()
3041 remove_proc_entry("igmp", net->proc_net); in igmp_net_init()
3043 return -ENOMEM; in igmp_net_init()
3048 remove_proc_entry("mcfilter", net->proc_net); in igmp_net_exit()
3049 remove_proc_entry("igmp", net->proc_net); in igmp_net_exit()
3050 inet_ctl_sock_destroy(net->ipv4.mc_autojoin_sk); in igmp_net_exit()