Fix for multicast session timeouts

Malcolm Beattie (malcolm.beattie@computing-services.oxford.ac.uk)
Fri, 26 Jul 1996 17:08:02 +0100 (BST)


I've finally tracked down the cause(s) of the multicast session
timeout problems and fixed it. The symptom is that about 5 minutes
after a multicast group is joined, packets stop reaching it (and
the nearest mrouted has in fact pruned it back). For example, an
mbone vic session only lasts five minutes before the picture freezes.

Here's the fix to net/ipv4/igmp.c: a couple of timing fixes and,
most importantly, the fact the igmp_rcv dropped the packet if
ttl > 1 instead of ttl < 1 and so the HOST_MEMBERSHIP_QUERY IGMP
requests sent out periodically by the router were never processed.

------------------------------ cut here ------------------------------
*** igmp.c.ORI Thu Jul 25 17:02:21 1996
--- igmp.c Fri Jul 26 16:54:00 1996
***************
*** 56,61 ****
--- 56,66 ----
* Christian Daudt : igmp_heard_report now only calls
* igmp_timer_expire if tm->running is
* true (960216).
+ * Malcolm Beattie : ttl comparison wrong in igmp_rcv made
+ * igmp_heard_query never trigger. Expiry
+ * miscalculation fixed in igmp_heard_query
+ * and random() made to return unsigned to
+ * prevent negative expiry times.
*/


***************
*** 207,213 ****
}
}

! extern __inline__ int random(void)
{
static unsigned long seed=152L;
seed=seed*69069L+1;
--- 212,218 ----
}
}

! extern __inline__ unsigned int random(void)
{
static unsigned long seed=152L;
seed=seed*69069L+1;
***************
*** 326,332 ****
{
if(im->tm_running)
{
! if(im->timer.expires>max_resp_time*HZ/IGMP_TIMER_SCALE)
{
igmp_stop_timer(im);
igmp_start_timer(im,max_resp_time);
--- 331,337 ----
{
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);
***************
*** 447,453 ****
}
ih=(struct igmphdr *)skb->h.raw;

! if(skb->len <sizeof(struct igmphdr) || skb->ip_hdr->ttl>1 || ip_compute_csum((void *)skb->h.raw,sizeof(struct igmphdr)))
{
kfree_skb(skb, FREE_READ);
return 0;
--- 452,458 ----
}
ih=(struct igmphdr *)skb->h.raw;

! if(skb->len <sizeof(struct igmphdr) || skb->ip_hdr->ttl<1 || ip_compute_csum((void *)skb->h.raw,sizeof(struct igmphdr)))
{
kfree_skb(skb, FREE_READ);
return 0;
------------------------------ cut here ------------------------------

--Malcolm

-- 
Malcolm Beattie <mbeattie@sable.ox.ac.uk>
Unix Systems Programmer
Oxford University Computing Services