Lines Matching refs:im

167 static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
177 static void ip_ma_put(struct ip_mc_list *im) in ip_ma_put() argument
179 if (atomic_dec_and_test(&im->refcnt)) { in ip_ma_put()
180 in_dev_put(im->interface); in ip_ma_put()
181 kfree_rcu(im, rcu); in ip_ma_put()
201 static void igmp_stop_timer(struct ip_mc_list *im) in igmp_stop_timer() argument
203 spin_lock_bh(&im->lock); in igmp_stop_timer()
204 if (del_timer(&im->timer)) in igmp_stop_timer()
205 atomic_dec(&im->refcnt); in igmp_stop_timer()
206 im->tm_running = 0; in igmp_stop_timer()
207 im->reporter = 0; in igmp_stop_timer()
208 im->unsolicit_count = 0; in igmp_stop_timer()
209 spin_unlock_bh(&im->lock); in igmp_stop_timer()
213 static void igmp_start_timer(struct ip_mc_list *im, int max_delay) in igmp_start_timer() argument
217 im->tm_running = 1; in igmp_start_timer()
218 if (!mod_timer(&im->timer, jiffies+tv+2)) in igmp_start_timer()
219 atomic_inc(&im->refcnt); in igmp_start_timer()
239 static void igmp_mod_timer(struct ip_mc_list *im, int max_delay) in igmp_mod_timer() argument
241 spin_lock_bh(&im->lock); in igmp_mod_timer()
242 im->unsolicit_count = 0; in igmp_mod_timer()
243 if (del_timer(&im->timer)) { in igmp_mod_timer()
244 if ((long)(im->timer.expires-jiffies) < max_delay) { in igmp_mod_timer()
245 add_timer(&im->timer); in igmp_mod_timer()
246 im->tm_running = 1; in igmp_mod_timer()
247 spin_unlock_bh(&im->lock); in igmp_mod_timer()
250 atomic_dec(&im->refcnt); in igmp_mod_timer()
252 igmp_start_timer(im, max_delay); in igmp_mod_timer()
253 spin_unlock_bh(&im->lock); in igmp_mod_timer()
766 struct ip_mc_list *im = (struct ip_mc_list *)data; in igmp_timer_expire() local
767 struct in_device *in_dev = im->interface; in igmp_timer_expire()
769 spin_lock(&im->lock); in igmp_timer_expire()
770 im->tm_running = 0; in igmp_timer_expire()
772 if (im->unsolicit_count) { in igmp_timer_expire()
773 im->unsolicit_count--; in igmp_timer_expire()
774 igmp_start_timer(im, unsolicited_report_interval(in_dev)); in igmp_timer_expire()
776 im->reporter = 1; in igmp_timer_expire()
777 spin_unlock(&im->lock); in igmp_timer_expire()
780 igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT); in igmp_timer_expire()
782 igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT); in igmp_timer_expire()
784 igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT); in igmp_timer_expire()
786 ip_ma_put(im); in igmp_timer_expire()
848 struct ip_mc_list *im; in igmp_heard_report() local
856 for_each_pmc_rcu(in_dev, im) { in igmp_heard_report()
857 if (im->multiaddr == group) { in igmp_heard_report()
858 igmp_stop_timer(im); in igmp_heard_report()
872 struct ip_mc_list *im; in igmp_heard_query() local
953 for_each_pmc_rcu(in_dev, im) { in igmp_heard_query()
956 if (group && group != im->multiaddr) in igmp_heard_query()
958 if (im->multiaddr == IGMP_ALL_HOSTS) in igmp_heard_query()
960 spin_lock_bh(&im->lock); in igmp_heard_query()
961 if (im->tm_running) in igmp_heard_query()
962 im->gsquery = im->gsquery && mark; in igmp_heard_query()
964 im->gsquery = mark; in igmp_heard_query()
965 changed = !im->gsquery || in igmp_heard_query()
966 igmp_marksources(im, ntohs(ih3->nsrcs), ih3->srcs); in igmp_heard_query()
967 spin_unlock_bh(&im->lock); in igmp_heard_query()
969 igmp_mod_timer(im, max_delay); in igmp_heard_query()
1071 static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im) in igmpv3_add_delrec() argument
1084 spin_lock_bh(&im->lock); in igmpv3_add_delrec()
1085 pmc->interface = im->interface; in igmpv3_add_delrec()
1087 pmc->multiaddr = im->multiaddr; in igmpv3_add_delrec()
1089 pmc->sfmode = im->sfmode; in igmpv3_add_delrec()
1093 pmc->tomb = im->tomb; in igmpv3_add_delrec()
1094 pmc->sources = im->sources; in igmpv3_add_delrec()
1095 im->tomb = im->sources = NULL; in igmpv3_add_delrec()
1099 spin_unlock_bh(&im->lock); in igmpv3_add_delrec()
1169 static void igmp_group_dropped(struct ip_mc_list *im) in igmp_group_dropped() argument
1171 struct in_device *in_dev = im->interface; in igmp_group_dropped()
1176 if (im->loaded) { in igmp_group_dropped()
1177 im->loaded = 0; in igmp_group_dropped()
1178 ip_mc_filter_del(in_dev, im->multiaddr); in igmp_group_dropped()
1182 if (im->multiaddr == IGMP_ALL_HOSTS) in igmp_group_dropped()
1185 reporter = im->reporter; in igmp_group_dropped()
1186 igmp_stop_timer(im); in igmp_group_dropped()
1193 igmp_send_report(in_dev, im, IGMP_HOST_LEAVE_MESSAGE); in igmp_group_dropped()
1197 igmpv3_add_delrec(in_dev, im); in igmp_group_dropped()
1204 static void igmp_group_added(struct ip_mc_list *im) in igmp_group_added() argument
1206 struct in_device *in_dev = im->interface; in igmp_group_added()
1208 if (im->loaded == 0) { in igmp_group_added()
1209 im->loaded = 1; in igmp_group_added()
1210 ip_mc_filter_add(in_dev, im->multiaddr); in igmp_group_added()
1214 if (im->multiaddr == IGMP_ALL_HOSTS) in igmp_group_added()
1220 spin_lock_bh(&im->lock); in igmp_group_added()
1221 igmp_start_timer(im, IGMP_INITIAL_REPORT_DELAY); in igmp_group_added()
1222 spin_unlock_bh(&im->lock); in igmp_group_added()
1227 im->crcount = in_dev->mr_qrv ?: sysctl_igmp_qrv; in igmp_group_added()
1237 static u32 ip_mc_hash(const struct ip_mc_list *im) in ip_mc_hash() argument
1239 return hash_32((__force u32)im->multiaddr, MC_HASH_SZ_LOG); in ip_mc_hash()
1243 struct ip_mc_list *im) in ip_mc_hash_add() argument
1250 hash = ip_mc_hash(im); in ip_mc_hash_add()
1251 im->next_hash = mc_hash[hash]; in ip_mc_hash_add()
1252 rcu_assign_pointer(mc_hash[hash], im); in ip_mc_hash_add()
1265 for_each_pmc_rtnl(in_dev, im) { in ip_mc_hash_add()
1266 hash = ip_mc_hash(im); in ip_mc_hash_add()
1267 im->next_hash = mc_hash[hash]; in ip_mc_hash_add()
1268 RCU_INIT_POINTER(mc_hash[hash], im); in ip_mc_hash_add()
1275 struct ip_mc_list *im) in ip_mc_hash_remove() argument
1282 mc_hash += ip_mc_hash(im); in ip_mc_hash_remove()
1283 while ((aux = rtnl_dereference(*mc_hash)) != im) in ip_mc_hash_remove()
1285 *mc_hash = im->next_hash; in ip_mc_hash_remove()
1295 struct ip_mc_list *im; in ip_mc_inc_group() local
1299 for_each_pmc_rtnl(in_dev, im) { in ip_mc_inc_group()
1300 if (im->multiaddr == addr) { in ip_mc_inc_group()
1301 im->users++; in ip_mc_inc_group()
1307 im = kzalloc(sizeof(*im), GFP_KERNEL); in ip_mc_inc_group()
1308 if (!im) in ip_mc_inc_group()
1311 im->users = 1; in ip_mc_inc_group()
1312 im->interface = in_dev; in ip_mc_inc_group()
1314 im->multiaddr = addr; in ip_mc_inc_group()
1316 im->sfmode = MCAST_EXCLUDE; in ip_mc_inc_group()
1317 im->sfcount[MCAST_EXCLUDE] = 1; in ip_mc_inc_group()
1318 atomic_set(&im->refcnt, 1); in ip_mc_inc_group()
1319 spin_lock_init(&im->lock); in ip_mc_inc_group()
1321 setup_timer(&im->timer, igmp_timer_expire, (unsigned long)im); in ip_mc_inc_group()
1322 im->unsolicit_count = sysctl_igmp_qrv; in ip_mc_inc_group()
1325 im->next_rcu = in_dev->mc_list; in ip_mc_inc_group()
1327 rcu_assign_pointer(in_dev->mc_list, im); in ip_mc_inc_group()
1329 ip_mc_hash_add(in_dev, im); in ip_mc_inc_group()
1332 igmpv3_del_delrec(in_dev, im->multiaddr); in ip_mc_inc_group()
1334 igmp_group_added(im); in ip_mc_inc_group()
1348 struct ip_mc_list *im; in ip_mc_rejoin_groups() local
1353 for_each_pmc_rtnl(in_dev, im) { in ip_mc_rejoin_groups()
1354 if (im->multiaddr == IGMP_ALL_HOSTS) in ip_mc_rejoin_groups()
1366 igmp_send_report(in_dev, im, type); in ip_mc_rejoin_groups()
2385 struct ip_mc_list *im; in ip_check_mc_rcu() local
2394 for (im = rcu_dereference(mc_hash[hash]); in ip_check_mc_rcu()
2395 im != NULL; in ip_check_mc_rcu()
2396 im = rcu_dereference(im->next_hash)) { in ip_check_mc_rcu()
2397 if (im->multiaddr == mc_addr) in ip_check_mc_rcu()
2401 for_each_pmc_rcu(in_dev, im) { in ip_check_mc_rcu()
2402 if (im->multiaddr == mc_addr) in ip_check_mc_rcu()
2406 if (im && proto == IPPROTO_IGMP) { in ip_check_mc_rcu()
2408 } else if (im) { in ip_check_mc_rcu()
2410 for (psf = im->sources; psf; psf = psf->sf_next) { in ip_check_mc_rcu()
2417 im->sfcount[MCAST_EXCLUDE]; in ip_check_mc_rcu()
2419 rv = im->sfcount[MCAST_EXCLUDE] != 0; in ip_check_mc_rcu()
2438 struct ip_mc_list *im = NULL; in igmp_mc_get_first() local
2448 im = rcu_dereference(in_dev->mc_list); in igmp_mc_get_first()
2449 if (im) { in igmp_mc_get_first()
2454 return im; in igmp_mc_get_first()
2457 static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_list *im) in igmp_mc_get_next() argument
2461 im = rcu_dereference(im->next_rcu); in igmp_mc_get_next()
2462 while (!im) { in igmp_mc_get_next()
2471 im = rcu_dereference(state->in_dev->mc_list); in igmp_mc_get_next()
2473 return im; in igmp_mc_get_next()
2478 struct ip_mc_list *im = igmp_mc_get_first(seq); in igmp_mc_get_idx() local
2479 if (im) in igmp_mc_get_idx()
2480 while (pos && (im = igmp_mc_get_next(seq, im)) != NULL) in igmp_mc_get_idx()
2482 return pos ? NULL : im; in igmp_mc_get_idx()
2494 struct ip_mc_list *im; in igmp_mc_seq_next() local
2496 im = igmp_mc_get_first(seq); in igmp_mc_seq_next()
2498 im = igmp_mc_get_next(seq, v); in igmp_mc_seq_next()
2500 return im; in igmp_mc_seq_next()
2519 struct ip_mc_list *im = (struct ip_mc_list *)v; in igmp_mc_seq_show() local
2532 if (rcu_access_pointer(state->in_dev->mc_list) == im) { in igmp_mc_seq_show()
2537 delta = im->timer.expires - jiffies; in igmp_mc_seq_show()
2540 im->multiaddr, im->users, in igmp_mc_seq_show()
2541 im->tm_running, in igmp_mc_seq_show()
2542 im->tm_running ? jiffies_delta_to_clock_t(delta) : 0, in igmp_mc_seq_show()
2543 im->reporter); in igmp_mc_seq_show()
2573 struct ip_mc_list *im; member
2582 struct ip_mc_list *im = NULL; in igmp_mcf_get_first() local
2586 state->im = NULL; in igmp_mcf_get_first()
2592 im = rcu_dereference(idev->mc_list); in igmp_mcf_get_first()
2593 if (likely(im)) { in igmp_mcf_get_first()
2594 spin_lock_bh(&im->lock); in igmp_mcf_get_first()
2595 psf = im->sources; in igmp_mcf_get_first()
2597 state->im = im; in igmp_mcf_get_first()
2601 spin_unlock_bh(&im->lock); in igmp_mcf_get_first()
2613 spin_unlock_bh(&state->im->lock); in igmp_mcf_get_next()
2614 state->im = state->im->next; in igmp_mcf_get_next()
2615 while (!state->im) { in igmp_mcf_get_next()
2624 state->im = rcu_dereference(state->idev->mc_list); in igmp_mcf_get_next()
2626 if (!state->im) in igmp_mcf_get_next()
2628 spin_lock_bh(&state->im->lock); in igmp_mcf_get_next()
2629 psf = state->im->sources; in igmp_mcf_get_next()
2666 if (likely(state->im)) { in igmp_mcf_seq_stop()
2667 spin_unlock_bh(&state->im->lock); in igmp_mcf_seq_stop()
2668 state->im = NULL; in igmp_mcf_seq_stop()
2687 ntohl(state->im->multiaddr), in igmp_mcf_seq_show()