aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Manley <william.manley@youview.com>2013-08-06 14:03:15 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-09 14:27:46 -0400
commit2690048c01f32bf45d1c1e1ab3079bc10ad2aea7 (patch)
treecea915b84e7edb59efaab7378ae0ffd8e5550b93
parent5c6fe01c1fe3140a8fb088d2a9c32548b731c35e (diff)
net: igmp: Allow user-space configuration of igmp unsolicited report interval
Adds the new procfs knobs: /proc/sys/net/ipv4/conf/*/igmpv2_unsolicited_report_interval /proc/sys/net/ipv4/conf/*/igmpv3_unsolicited_report_interval Which will allow userspace configuration of the IGMP unsolicited report interval (see below) in milliseconds. The defaults are 10000ms for IGMPv2 and 1000ms for IGMPv3 in accordance with RFC2236 and RFC3376. Background: 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". Prior to this patch this value was hard coded in the kernel to 10s for IGMPv2 and 1s for IGMPv3. 10s is unsuitable for some use-cases, such as IPTV as it can cause channel change to be slow in the presence of packet loss. This patch allows the value to be overridden from userspace for both IGMPv2 and IGMPv3 such that it can be tuned accoding to the network. 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 the procfs knobs. igmpvX_unsolicited_report_interval is intended to follow the pattern established by force_igmp_version, and while a procfs entry has been added a corresponding sysctl knob has not as it is my understanding that sysctl is deprecated[1]. [1]: http://lwn.net/Articles/247243/ 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>
-rw-r--r--include/linux/inetdevice.h2
-rw-r--r--net/ipv4/devinet.c8
-rw-r--r--net/ipv4/igmp.c19
3 files changed, 27 insertions, 2 deletions
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 0a4a6cb35338..c796ce26c7c0 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -28,6 +28,8 @@ enum
28 IPV4_DEVCONF_ARPFILTER, 28 IPV4_DEVCONF_ARPFILTER,
29 IPV4_DEVCONF_MEDIUM_ID, 29 IPV4_DEVCONF_MEDIUM_ID,
30 IPV4_DEVCONF_FORCE_IGMP_VERSION, 30 IPV4_DEVCONF_FORCE_IGMP_VERSION,
31 IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL,
32 IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL,
31 IPV4_DEVCONF_NOXFRM, 33 IPV4_DEVCONF_NOXFRM,
32 IPV4_DEVCONF_NOPOLICY, 34 IPV4_DEVCONF_NOPOLICY,
33 IPV4_DEVCONF_ARP_ANNOUNCE, 35 IPV4_DEVCONF_ARP_ANNOUNCE,
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 87d47ce9fa33..a1b5bcbd04ae 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -73,6 +73,8 @@ static struct ipv4_devconf ipv4_devconf = {
73 [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1, 73 [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
74 [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1, 74 [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
75 [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1, 75 [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
76 [IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL - 1] = 10000 /*ms*/,
77 [IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL - 1] = 1000 /*ms*/,
76 }, 78 },
77}; 79};
78 80
@@ -83,6 +85,8 @@ static struct ipv4_devconf ipv4_devconf_dflt = {
83 [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1, 85 [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
84 [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1, 86 [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
85 [IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE - 1] = 1, 87 [IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
88 [IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL - 1] = 10000 /*ms*/,
89 [IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL - 1] = 1000 /*ms*/,
86 }, 90 },
87}; 91};
88 92
@@ -2096,6 +2100,10 @@ static struct devinet_sysctl_table {
2096 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"), 2100 DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
2097 DEVINET_SYSCTL_RW_ENTRY(FORCE_IGMP_VERSION, 2101 DEVINET_SYSCTL_RW_ENTRY(FORCE_IGMP_VERSION,
2098 "force_igmp_version"), 2102 "force_igmp_version"),
2103 DEVINET_SYSCTL_RW_ENTRY(IGMPV2_UNSOLICITED_REPORT_INTERVAL,
2104 "igmpv2_unsolicited_report_interval"),
2105 DEVINET_SYSCTL_RW_ENTRY(IGMPV3_UNSOLICITED_REPORT_INTERVAL,
2106 "igmpv3_unsolicited_report_interval"),
2099 2107
2100 DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"), 2108 DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
2101 DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"), 2109 DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index ceb19ab9cf9d..d6c0e64ec97f 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -142,10 +142,25 @@
142 142
143static int unsolicited_report_interval(struct in_device *in_dev) 143static int unsolicited_report_interval(struct in_device *in_dev)
144{ 144{
145 int interval_ms, interval_jiffies;
146
145 if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) 147 if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev))
146 return IGMP_V2_Unsolicited_Report_Interval; 148 interval_ms = IN_DEV_CONF_GET(
149 in_dev,
150 IGMPV2_UNSOLICITED_REPORT_INTERVAL);
147 else /* v3 */ 151 else /* v3 */
148 return IGMP_V3_Unsolicited_Report_Interval; 152 interval_ms = IN_DEV_CONF_GET(
153 in_dev,
154 IGMPV3_UNSOLICITED_REPORT_INTERVAL);
155
156 interval_jiffies = msecs_to_jiffies(interval_ms);
157
158 /* _timer functions can't handle a delay of 0 jiffies so ensure
159 * we always return a positive value.
160 */
161 if (interval_jiffies <= 0)
162 interval_jiffies = 1;
163 return interval_jiffies;
149} 164}
150 165
151static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); 166static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);