--- zzzz-none-000/linux-2.6.19.2/net/ipv4/igmp.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/net/ipv4/igmp.c 2008-07-17 16:07:16.000000000 +0000 @@ -114,7 +114,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 @@ -282,6 +282,8 @@ return scount; } +int sysctl_igmp_tos __read_mostly = 0xc0; + static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) { struct sk_buff *skb; @@ -295,8 +297,7 @@ { struct flowi fl = { .oif = dev->ifindex, - .nl_u = { .ip4_u = { - .daddr = IGMPV3_ALL_MCR } }, + .nl_u = { .ip4_u = { .daddr = IGMPV3_ALL_MCR, .saddr = 0 } }, .proto = IPPROTO_IGMP }; if (ip_route_output_key(&rt, &fl)) { kfree_skb(skb); @@ -318,7 +319,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; @@ -666,7 +667,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; @@ -1177,8 +1178,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 } @@ -1193,7 +1195,7 @@ * A socket has joined a multicast group on device dev. */ -void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) +void ip_mc_inc_group_for_mode(struct in_device *in_dev, __be32 addr, int omode) { struct ip_mc_list *im; @@ -1202,7 +1204,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; } } @@ -1216,9 +1218,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; @@ -1248,6 +1256,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 */ @@ -1400,7 +1413,6 @@ int sysctl_igmp_max_memberships __read_mostly = IP_MAX_MEMBERSHIPS; int sysctl_igmp_max_msf __read_mostly = IP_MAX_MSF; - static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, __be32 *psfsrc) { @@ -1714,7 +1726,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; __be32 addr = imr->imr_multiaddr.s_addr; @@ -1755,15 +1767,20 @@ memcpy(&iml->multi, imr, sizeof(*imr)); iml->next = inet->mc_list; iml->sflist = NULL; - iml->sfmode = MCAST_EXCLUDE; - inet->mc_list = iml; - ip_mc_inc_group(in_dev, addr); + iml->sfmode = omode; + inet->mc_list = iml; + ip_mc_inc_group_for_mode(in_dev, addr, omode); err = 0; done: rtnl_unlock(); 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) { @@ -2594,3 +2611,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);