static void igmp_timer_expire(unsigned long data) { struct ip_mc_list *im=(struct ip_mc_list *)data; struct in_device *in_dev = im->interface; int err; im->tm_running=0; if (IGMP_V1_SEEN(in_dev)) err = igmp_send_report(in_dev->dev, im->multiaddr, IGMP_HOST_MEMBERSHIP_REPORT); else err = igmp_send_report(in_dev->dev, im->multiaddr, IGMP_HOST_NEW_MEMBERSHIP_REPORT); /* Failed. Retry later. */ if (err) { igmp_start_timer(im, IGMP_Unsolicited_Report_Interval); return; } if (im->unsolicit_count) { im->unsolicit_count--; igmp_start_timer(im, IGMP_Unsolicited_Report_Interval); } im->reporter = 1; }
static void igmp_heard_query(struct device *dev) { struct ip_mc_list *im; for(im=dev->ip_mc_list;im!=NULL;im=im->next) if(!im->tm_running && im->multiaddr!=IGMP_ALL_HOSTS) igmp_start_timer(im); }
static void igmp_group_added(struct ip_mc_list *im) { if (im->loaded == 0) { im->loaded = 1; ip_mc_filter_add(im->interface, im->multiaddr); } #ifdef CONFIG_IP_MULTICAST if (im->multiaddr == IGMP_ALL_HOSTS) return; start_bh_atomic(); igmp_start_timer(im, IGMP_Initial_Report_Delay); end_bh_atomic(); #endif }
static void igmp_mod_timer(struct ip_mc_list *im, int max_delay) { spin_lock_bh(&im->lock); im->unsolicit_count = 0; if (del_timer(&im->timer)) { if ((long)(im->timer.expires-jiffies) < max_delay) { add_timer(&im->timer); im->tm_running=1; spin_unlock_bh(&im->lock); return; } atomic_dec(&im->refcnt); } igmp_start_timer(im, max_delay); spin_unlock_bh(&im->lock); }
static void igmp_timer_expire(unsigned long data) { struct ip_mc_list *im=(struct ip_mc_list *)data; struct in_device *in_dev = im->interface; spin_lock(&im->lock); im->tm_running=0; if (im->unsolicit_count) { im->unsolicit_count--; igmp_start_timer(im, IGMP_Unsolicited_Report_Interval); } im->reporter = 1; spin_unlock(&im->lock); if (IGMP_V1_SEEN(in_dev)) igmp_send_report(in_dev->dev, im->multiaddr, IGMP_HOST_MEMBERSHIP_REPORT); else igmp_send_report(in_dev->dev, im->multiaddr, IGMP_HOST_NEW_MEMBERSHIP_REPORT); ip_ma_put(im); }
static void igmp_heard_query(struct in_device *in_dev, unsigned char max_resp_time, u32 group) { struct ip_mc_list *im; int max_delay; max_delay = max_resp_time*(HZ/IGMP_TIMER_SCALE); if (max_resp_time == 0) { /* Alas, old v1 router presents here. */ max_delay = IGMP_Query_Response_Interval; in_dev->mr_v1_seen = jiffies + IGMP_V1_Router_Present_Timeout; group = 0; } /* * - Start the timers in all of our membership records * that the query applies to for the interface on * which the query arrived excl. those that belong * to a "local" group (224.0.0.X) * - For timers already running check if they need to * be reset. * - Use the igmp->igmp_code field as the maximum * delay possible */ for (im=in_dev->mc_list; im!=NULL; im=im->next) { if (group && group != im->multiaddr) continue; if (im->multiaddr == IGMP_ALL_HOSTS) continue; im->unsolicit_count = 0; if (im->tm_running && (long)(im->timer.expires-jiffies) > max_delay) igmp_stop_timer(im); igmp_start_timer(im, max_delay); } }
static void igmp_heard_query(struct device *dev,unsigned char max_resp_time) { struct ip_mc_list *im; int mrouter_type; /* * The max_resp_time is in units of 1/10 second. */ if(max_resp_time>0) { mrouter_type=IGMP_NEW_ROUTER; if(igmp_set_mrouter_info(dev,mrouter_type,0)==NULL) return; /* * - Start the timers in all of our membership records * that the query applies to for the interface on * which the query arrived excl. those that belong * to a "local" group (224.0.0.X) * - For timers already running check if they need to * be reset. * - Use the igmp->igmp_code field as the maximum * delay possible */ for(im=dev->ip_mc_list;im!=NULL;im=im->next) { if(im->tm_running) { if(im->timer.expires>jiffies+max_resp_time*HZ/IGMP_TIMER_SCALE) { igmp_stop_timer(im); igmp_start_timer(im,max_resp_time); } } else { if((im->multiaddr & IGMP_LOCAL_GROUP_MASK)!=IGMP_LOCAL_GROUP) igmp_start_timer(im,max_resp_time); } } } else { mrouter_type=IGMP_OLD_ROUTER; max_resp_time=IGMP_MAX_HOST_REPORT_DELAY*IGMP_TIMER_SCALE; if(igmp_set_mrouter_info(dev,mrouter_type,IGMP_AGE_THRESHOLD)==NULL) return; /* * Start the timers in all of our membership records for * the interface on which the query arrived, except those * that are already running and those that belong to a * "local" group (224.0.0.X). */ for(im=dev->ip_mc_list;im!=NULL;im=im->next) { if(!im->tm_running && (im->multiaddr & IGMP_LOCAL_GROUP_MASK)!=IGMP_LOCAL_GROUP) igmp_start_timer(im,max_resp_time); } } }