aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/igmp.c
diff options
context:
space:
mode:
authorWilliam Manley <william.manley@youview.com>2013-08-06 14:03:13 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-09 14:27:46 -0400
commitcab70040dfd95ee32144f02fade64f0cb94f31a0 (patch)
tree0deaa52ea74518733b85c0527d57f3e1a3b11d6d /net/ipv4/igmp.c
parentb20903f2a9ee5bd9ca80ad72867c8d137aaf4d62 (diff)
net: igmp: Reduce Unsolicited report interval to 1s when using IGMPv3
If an IGMP join packet is lost you will not receive data sent to the multicast group so if no data arrives from that multicast group in a period of time after the IGMP join a second IGMP join will be sent. The delay between joins is the "IGMP Unsolicited Report Interval". Previously this value was hard coded to be chosen randomly between 0-10s. This can be too long for some use-cases, such as IPTV as it can cause channel change to be slow in the presence of packet loss. The value 10s has come from IGMPv2 RFC2236, which was reduced to 1s in IGMPv3 RFC3376. This patch makes the kernel use the 1s value from the later RFC if we are operating in IGMPv3 mode. IGMPv2 behaviour is unaffected. Tested with Wireshark and a simple program to join a (non-existent) multicast group. The distribution of timings for the second join differ based upon setting /proc/sys/net/ipv4/conf/eth0/force_igmp_version. Signed-off-by: William Manley <william.manley@youview.com> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Acked-by: Benjamin LaHaise <bcrl@kvack.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r--net/ipv4/igmp.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index ef7618630f36..ceb19ab9cf9d 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -114,7 +114,8 @@
114 114
115#define IGMP_V1_Router_Present_Timeout (400*HZ) 115#define IGMP_V1_Router_Present_Timeout (400*HZ)
116#define IGMP_V2_Router_Present_Timeout (400*HZ) 116#define IGMP_V2_Router_Present_Timeout (400*HZ)
117#define IGMP_Unsolicited_Report_Interval (10*HZ) 117#define IGMP_V2_Unsolicited_Report_Interval (10*HZ)
118#define IGMP_V3_Unsolicited_Report_Interval (1*HZ)
118#define IGMP_Query_Response_Interval (10*HZ) 119#define IGMP_Query_Response_Interval (10*HZ)
119#define IGMP_Unsolicited_Report_Count 2 120#define IGMP_Unsolicited_Report_Count 2
120 121
@@ -139,6 +140,14 @@
139 ((in_dev)->mr_v2_seen && \ 140 ((in_dev)->mr_v2_seen && \
140 time_before(jiffies, (in_dev)->mr_v2_seen))) 141 time_before(jiffies, (in_dev)->mr_v2_seen)))
141 142
143static int unsolicited_report_interval(struct in_device *in_dev)
144{
145 if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev))
146 return IGMP_V2_Unsolicited_Report_Interval;
147 else /* v3 */
148 return IGMP_V3_Unsolicited_Report_Interval;
149}
150
142static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); 151static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
143static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); 152static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);
144static void igmpv3_clear_delrec(struct in_device *in_dev); 153static void igmpv3_clear_delrec(struct in_device *in_dev);
@@ -722,7 +731,8 @@ static void igmp_ifc_timer_expire(unsigned long data)
722 igmpv3_send_cr(in_dev); 731 igmpv3_send_cr(in_dev);
723 if (in_dev->mr_ifc_count) { 732 if (in_dev->mr_ifc_count) {
724 in_dev->mr_ifc_count--; 733 in_dev->mr_ifc_count--;
725 igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval); 734 igmp_ifc_start_timer(in_dev,
735 unsolicited_report_interval(in_dev));
726 } 736 }
727 __in_dev_put(in_dev); 737 __in_dev_put(in_dev);
728} 738}
@@ -747,7 +757,7 @@ static void igmp_timer_expire(unsigned long data)
747 757
748 if (im->unsolicit_count) { 758 if (im->unsolicit_count) {
749 im->unsolicit_count--; 759 im->unsolicit_count--;
750 igmp_start_timer(im, IGMP_Unsolicited_Report_Interval); 760 igmp_start_timer(im, unsolicited_report_interval(in_dev));
751 } 761 }
752 im->reporter = 1; 762 im->reporter = 1;
753 spin_unlock(&im->lock); 763 spin_unlock(&im->lock);