--- zzzz-none-000/linux-2.6.13.1/net/ipv4/igmp.c 2005-09-10 02:42:58.000000000 +0000 +++ ohio-7170-487/linux-2.6.13.1/net/ipv4/igmp.c 2008-07-17 16:07:56.000000000 +0000 @@ -113,7 +113,7 @@ #define IGMP_V1_Router_Present_Timeout (400*HZ) #define IGMP_V2_Router_Present_Timeout (400*HZ) -#define IGMP_Unsolicited_Report_Interval (10*HZ) +#define IGMP_Unsolicited_Report_Interval (1*HZ) #define IGMP_Query_Response_Interval (10*HZ) #define IGMP_Unsolicited_Report_Count 2 @@ -270,6 +270,8 @@ return scount; } +int sysctl_igmp_tos = 0xc0; + static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) { struct sk_buff *skb; @@ -306,7 +308,7 @@ pip->version = 4; pip->ihl = (sizeof(struct iphdr)+4)>>2; - pip->tos = 0xc0; + pip->tos = sysctl_igmp_tos & 0xff; pip->frag_off = htons(IP_DF); pip->ttl = 1; pip->daddr = rt->rt_dst; @@ -652,7 +654,7 @@ iph->version = 4; iph->ihl = (sizeof(struct iphdr)+4)>>2; - iph->tos = 0xc0; + iph->tos = sysctl_igmp_tos & 0xff; iph->frag_off = htons(IP_DF); iph->ttl = 1; iph->daddr = dst; @@ -1111,8 +1113,9 @@ } /* else, v3 */ - im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : - IGMP_Unsolicited_Report_Count; + if (im->sfmode == MCAST_EXCLUDE) + im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : + IGMP_Unsolicited_Report_Count; igmp_ifc_event(in_dev); #endif } @@ -1127,7 +1130,7 @@ * A socket has joined a multicast group on device dev. */ -void ip_mc_inc_group(struct in_device *in_dev, u32 addr) +void ip_mc_inc_group_for_mode(struct in_device *in_dev, u32 addr, int omode) { struct ip_mc_list *im; @@ -1136,7 +1139,7 @@ for (im=in_dev->mc_list; im; im=im->next) { if (im->multiaddr == addr) { im->users++; - ip_mc_add_src(in_dev, &addr, MCAST_EXCLUDE, 0, NULL, 0); + ip_mc_add_src(in_dev, &addr, omode, 0, NULL, 0); goto out; } } @@ -1150,9 +1153,15 @@ in_dev_hold(in_dev); im->multiaddr=addr; /* initial mode is (EX, empty) */ - im->sfmode = MCAST_EXCLUDE; - im->sfcount[MCAST_INCLUDE] = 0; - im->sfcount[MCAST_EXCLUDE] = 1; + if (omode == MCAST_EXCLUDE) { + im->sfmode = MCAST_EXCLUDE; + im->sfcount[MCAST_INCLUDE] = 0; + im->sfcount[MCAST_EXCLUDE] = 1; + } else { + im->sfmode = MCAST_INCLUDE; + im->sfcount[MCAST_INCLUDE] = 1; + im->sfcount[MCAST_EXCLUDE] = 0; + } im->sources = NULL; im->tomb = NULL; im->crcount = 0; @@ -1182,6 +1191,11 @@ return; } +void ip_mc_inc_group(struct in_device *in_dev, u32 addr) +{ + ip_mc_inc_group_for_mode(in_dev, addr, MCAST_EXCLUDE); +} + /* * A socket has left a multicast group on device dev */ @@ -1611,7 +1625,7 @@ /* * Join a multicast group */ -int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) +int ip_mc_join_group_for_mode(struct sock *sk , struct ip_mreqn *imr, int omode) { int err; u32 addr = imr->imr_multiaddr.s_addr; @@ -1652,15 +1666,20 @@ memcpy(&iml->multi, imr, sizeof(*imr)); iml->next = inet->mc_list; iml->sflist = NULL; - iml->sfmode = MCAST_EXCLUDE; + iml->sfmode = omode; inet->mc_list = iml; - ip_mc_inc_group(in_dev, addr); + ip_mc_inc_group_for_mode(in_dev, addr, omode); err = 0; done: rtnl_shunlock(); return err; } +int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) +{ + return ip_mc_join_group_for_mode(sk, imr, MCAST_EXCLUDE); +} + static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, struct in_device *in_dev) { @@ -2485,3 +2504,4 @@ EXPORT_SYMBOL(ip_mc_dec_group); EXPORT_SYMBOL(ip_mc_inc_group); EXPORT_SYMBOL(ip_mc_join_group); +EXPORT_SYMBOL(ip_mc_join_group_for_mode);