Commit ba3b62bb authored by David Stevens's avatar David Stevens Committed by David S. Miller

[IPV4/IPV6]: Fix IGMP device refcount leaks, with help from yoshfuji@linux-ipv6.org.

parent 7976f8f6
......@@ -178,7 +178,7 @@ static void igmp_gq_start_timer(struct in_device *in_dev)
in_dev->mr_gq_running = 1;
if (!mod_timer(&in_dev->mr_gq_timer, jiffies+tv+2))
atomic_inc(&in_dev->refcnt);
in_dev_hold(in_dev);
}
static void igmp_ifc_start_timer(struct in_device *in_dev, int delay)
......@@ -186,7 +186,7 @@ static void igmp_ifc_start_timer(struct in_device *in_dev, int delay)
int tv = net_random() % delay;
if (!mod_timer(&in_dev->mr_ifc_timer, jiffies+tv+2))
atomic_inc(&in_dev->refcnt);
in_dev_hold(in_dev);
}
static void igmp_mod_timer(struct ip_mc_list *im, int max_delay)
......@@ -670,6 +670,7 @@ static void igmp_gq_timer_expire(unsigned long data)
in_dev->mr_gq_running = 0;
igmpv3_send_report(in_dev, 0);
__in_dev_put(in_dev);
}
static void igmp_ifc_timer_expire(unsigned long data)
......@@ -681,6 +682,7 @@ static void igmp_ifc_timer_expire(unsigned long data)
in_dev->mr_ifc_count--;
igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval);
}
__in_dev_put(in_dev);
}
static void igmp_ifc_event(struct in_device *in_dev)
......@@ -782,7 +784,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih,
/* cancel the interface change timer */
in_dev->mr_ifc_count = 0;
if (del_timer(&in_dev->mr_ifc_timer))
atomic_dec(&in_dev->refcnt);
__in_dev_put(in_dev);
/* clear deleted report items */
igmpv3_clear_delrec(in_dev);
} else if (len < 12) {
......@@ -1197,10 +1199,10 @@ void ip_mc_down(struct in_device *in_dev)
#ifdef CONFIG_IP_MULTICAST
in_dev->mr_ifc_count = 0;
if (del_timer(&in_dev->mr_ifc_timer))
atomic_dec(&in_dev->refcnt);
__in_dev_put(in_dev);
in_dev->mr_gq_running = 0;
if (del_timer(&in_dev->mr_gq_timer))
atomic_dec(&in_dev->refcnt);
__in_dev_put(in_dev);
#endif
for (i=in_dev->mc_list; i; i=i->next)
......
......@@ -1904,6 +1904,7 @@ static void mld_gq_timer_expire(unsigned long data)
idev->mc_gq_running = 0;
mld_send_report(idev, 0);
__in6_dev_put(idev);
}
static void mld_ifc_timer_expire(unsigned long data)
......@@ -1916,6 +1917,7 @@ static void mld_ifc_timer_expire(unsigned long data)
if (idev->mc_ifc_count)
mld_ifc_start_timer(idev, idev->mc_maxdelay);
}
__in6_dev_put(idev);
}
static void mld_ifc_event(struct inet6_dev *idev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment