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; }
int ip_mc_procinfo(char *buffer, char **start, off_t offset, int length) { off_t pos=0, begin=0; struct ip_mc_list *im; int len=0; struct net_device *dev; len=sprintf(buffer,"Idx\tDevice : Count Querier\tGroup Users Timer\tReporter\n"); read_lock(&dev_base_lock); for(dev = dev_base; dev; dev = dev->next) { struct in_device *in_dev = in_dev_get(dev); char *querier = "NONE"; if (in_dev == NULL) continue; querier = IGMP_V1_SEEN(in_dev) ? "V1" : "V2"; len+=sprintf(buffer+len,"%d\t%-10s: %5d %7s\n", dev->ifindex, dev->name, dev->mc_count, querier); read_lock(&in_dev->lock); for (im = in_dev->mc_list; im; im = im->next) { len+=sprintf(buffer+len, "\t\t\t\t%08lX %5d %d:%08lX\t\t%d\n", im->multiaddr, im->users, im->tm_running, im->timer.expires-jiffies, im->reporter); pos=begin+len; if(pos<offset) { len=0; begin=pos; } if(pos>offset+length) { read_unlock(&in_dev->lock); in_dev_put(in_dev); goto done; } } read_unlock(&in_dev->lock); in_dev_put(in_dev); } done: read_unlock(&dev_base_lock); *start=buffer+(offset-begin); len-=(offset-begin); if(len>length) len=length; if(len<0) len=0; return len; }
static void igmp_group_dropped(struct ip_mc_list *im) { if (im->loaded) { im->loaded = 0; ip_mc_filter_del(im->interface, im->multiaddr); } #ifdef CONFIG_IP_MULTICAST if (im->multiaddr == IGMP_ALL_HOSTS) return; start_bh_atomic(); igmp_stop_timer(im); end_bh_atomic(); if (im->reporter && !IGMP_V1_SEEN(im->interface)) igmp_send_report(im->interface->dev, im->multiaddr, IGMP_HOST_LEAVE_MESSAGE); #endif }
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); }