netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Hangbin Liu <liuhangbin@gmail.com>, Ying Xu <yinxu@redhat.com>,
	"David S . Miller" <davem@davemloft.net>,
	Sasha Levin <sashal@kernel.org>,
	netdev@vger.kernel.org
Subject: [PATCH AUTOSEL 4.19 142/237] ipv4/igmp: fix v1/v2 switchback timeout based on rfc3376, 8.12
Date: Sat, 16 Nov 2019 10:39:37 -0500	[thread overview]
Message-ID: <20191116154113.7417-142-sashal@kernel.org> (raw)
In-Reply-To: <20191116154113.7417-1-sashal@kernel.org>

From: Hangbin Liu <liuhangbin@gmail.com>

[ Upstream commit 966c37f2d77eb44d47af8e919267b1ba675b2eca ]

Similiar with ipv6 mcast commit 89225d1ce6af3 ("net: ipv6: mld: fix v1/v2
switchback timeout to rfc3810, 9.12.")

i) RFC3376 8.12. Older Version Querier Present Timeout says:

   The Older Version Querier Interval is the time-out for transitioning
   a host back to IGMPv3 mode once an older version query is heard.
   When an older version query is received, hosts set their Older
   Version Querier Present Timer to Older Version Querier Interval.

   This value MUST be ((the Robustness Variable) times (the Query
   Interval in the last Query received)) plus (one Query Response
   Interval).

Currently we only use a hardcode value IGMP_V1/v2_ROUTER_PRESENT_TIMEOUT.
Fix it by adding two new items mr_qi(Query Interval) and mr_qri(Query Response
Interval) in struct in_device.

Now we can calculate the switchback time via (mr_qrv * mr_qi) + mr_qri.
We need update these values when receive IGMPv3 queries.

Reported-by: Ying Xu <yinxu@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/linux/inetdevice.h |  4 ++-
 net/ipv4/igmp.c            | 53 ++++++++++++++++++++++++++------------
 2 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index c759d1cbcedd8..a64f21a97369a 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -37,7 +37,9 @@ struct in_device {
 	unsigned long		mr_v1_seen;
 	unsigned long		mr_v2_seen;
 	unsigned long		mr_maxdelay;
-	unsigned char		mr_qrv;
+	unsigned long		mr_qi;		/* Query Interval */
+	unsigned long		mr_qri;		/* Query Response Interval */
+	unsigned char		mr_qrv;		/* Query Robustness Variable */
 	unsigned char		mr_gq_running;
 	unsigned char		mr_ifc_count;
 	struct timer_list	mr_gq_timer;	/* general query timer */
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index b2240b7f225d5..523d26f5e22e2 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -111,13 +111,10 @@
 #ifdef CONFIG_IP_MULTICAST
 /* Parameter names and values are taken from igmp-v2-06 draft */
 
-#define IGMP_V1_ROUTER_PRESENT_TIMEOUT		(400*HZ)
-#define IGMP_V2_ROUTER_PRESENT_TIMEOUT		(400*HZ)
 #define IGMP_V2_UNSOLICITED_REPORT_INTERVAL	(10*HZ)
 #define IGMP_V3_UNSOLICITED_REPORT_INTERVAL	(1*HZ)
+#define IGMP_QUERY_INTERVAL			(125*HZ)
 #define IGMP_QUERY_RESPONSE_INTERVAL		(10*HZ)
-#define IGMP_QUERY_ROBUSTNESS_VARIABLE		2
-
 
 #define IGMP_INITIAL_REPORT_DELAY		(1)
 
@@ -953,13 +950,15 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
 
 			max_delay = IGMP_QUERY_RESPONSE_INTERVAL;
 			in_dev->mr_v1_seen = jiffies +
-				IGMP_V1_ROUTER_PRESENT_TIMEOUT;
+				(in_dev->mr_qrv * in_dev->mr_qi) +
+				in_dev->mr_qri;
 			group = 0;
 		} else {
 			/* v2 router present */
 			max_delay = ih->code*(HZ/IGMP_TIMER_SCALE);
 			in_dev->mr_v2_seen = jiffies +
-				IGMP_V2_ROUTER_PRESENT_TIMEOUT;
+				(in_dev->mr_qrv * in_dev->mr_qi) +
+				in_dev->mr_qri;
 		}
 		/* cancel the interface change timer */
 		in_dev->mr_ifc_count = 0;
@@ -999,8 +998,21 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
 		if (!max_delay)
 			max_delay = 1;	/* can't mod w/ 0 */
 		in_dev->mr_maxdelay = max_delay;
-		if (ih3->qrv)
-			in_dev->mr_qrv = ih3->qrv;
+
+		/* RFC3376, 4.1.6. QRV and 4.1.7. QQIC, when the most recently
+		 * received value was zero, use the default or statically
+		 * configured value.
+		 */
+		in_dev->mr_qrv = ih3->qrv ?: net->ipv4.sysctl_igmp_qrv;
+		in_dev->mr_qi = IGMPV3_QQIC(ih3->qqic)*HZ ?: IGMP_QUERY_INTERVAL;
+
+		/* RFC3376, 8.3. Query Response Interval:
+		 * The number of seconds represented by the [Query Response
+		 * Interval] must be less than the [Query Interval].
+		 */
+		if (in_dev->mr_qri >= in_dev->mr_qi)
+			in_dev->mr_qri = (in_dev->mr_qi/HZ - 1)*HZ;
+
 		if (!group) { /* general query */
 			if (ih3->nsrcs)
 				return true;	/* no sources allowed */
@@ -1738,18 +1750,30 @@ void ip_mc_down(struct in_device *in_dev)
 	ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS);
 }
 
-void ip_mc_init_dev(struct in_device *in_dev)
-{
 #ifdef CONFIG_IP_MULTICAST
+static void ip_mc_reset(struct in_device *in_dev)
+{
 	struct net *net = dev_net(in_dev->dev);
+
+	in_dev->mr_qi = IGMP_QUERY_INTERVAL;
+	in_dev->mr_qri = IGMP_QUERY_RESPONSE_INTERVAL;
+	in_dev->mr_qrv = net->ipv4.sysctl_igmp_qrv;
+}
+#else
+static void ip_mc_reset(struct in_device *in_dev)
+{
+}
 #endif
+
+void ip_mc_init_dev(struct in_device *in_dev)
+{
 	ASSERT_RTNL();
 
 #ifdef CONFIG_IP_MULTICAST
 	timer_setup(&in_dev->mr_gq_timer, igmp_gq_timer_expire, 0);
 	timer_setup(&in_dev->mr_ifc_timer, igmp_ifc_timer_expire, 0);
-	in_dev->mr_qrv = net->ipv4.sysctl_igmp_qrv;
 #endif
+	ip_mc_reset(in_dev);
 
 	spin_lock_init(&in_dev->mc_tomb_lock);
 }
@@ -1759,15 +1783,10 @@ void ip_mc_init_dev(struct in_device *in_dev)
 void ip_mc_up(struct in_device *in_dev)
 {
 	struct ip_mc_list *pmc;
-#ifdef CONFIG_IP_MULTICAST
-	struct net *net = dev_net(in_dev->dev);
-#endif
 
 	ASSERT_RTNL();
 
-#ifdef CONFIG_IP_MULTICAST
-	in_dev->mr_qrv = net->ipv4.sysctl_igmp_qrv;
-#endif
+	ip_mc_reset(in_dev);
 	ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);
 
 	for_each_pmc_rtnl(in_dev, pmc) {
-- 
2.20.1


  parent reply	other threads:[~2019-11-16 15:44 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20191116154113.7417-1-sashal@kernel.org>
2019-11-16 15:37 ` [PATCH AUTOSEL 4.19 016/237] mt76: do not store aggregation sequence number for null-data frames Sasha Levin
2019-11-16 15:37 ` [PATCH AUTOSEL 4.19 017/237] mt76x0: phy: fix restore phase in mt76x0_phy_recalibrate_after_assoc Sasha Levin
2019-11-16 15:37 ` [PATCH AUTOSEL 4.19 018/237] brcmsmac: AP mode: update beacon when TIM changes Sasha Levin
2019-11-16 15:37 ` [PATCH AUTOSEL 4.19 019/237] ath10k: set probe request oui during driver start Sasha Levin
2019-11-16 15:37 ` [PATCH AUTOSEL 4.19 020/237] ath10k: allocate small size dma memory in ath10k_pci_diag_write_mem Sasha Levin
2019-11-16 15:37 ` [PATCH AUTOSEL 4.19 037/237] net: ethernet: ti: cpsw: fix lost of mcast packets while rx_mode update Sasha Levin
2019-11-16 15:37 ` [PATCH AUTOSEL 4.19 044/237] qed: Align local and global PTT to propagate through the APIs Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 046/237] nfp: bpf: protect against mis-initializing atomic counters Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 066/237] net: dsa: mv88e6xxx: Fix 88E6141/6341 2500mbps SERDES speed Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 067/237] net: fix warning in af_unix Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 068/237] net: ena: Fix Kconfig dependency on X86 Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 079/237] sctp: use sk_wmem_queued to check for writable space Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 081/237] selftests/bpf: fix file resource leak in load_kallsyms Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 082/237] SUNRPC: Fix a compile warning for cmpxchg64() Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 083/237] sunrpc: safely reallow resvport min/max inversion Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 084/237] atm: zatm: Fix empty body Clang warnings Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 096/237] selftests/bpf: fix return value comparison for tests in test_libbpf.sh Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 097/237] tools: bpftool: fix completion for "bpftool map update" Sasha Levin
2019-11-16 15:38 ` [PATCH AUTOSEL 4.19 100/237] libceph: don't consume a ref on pagelist in ceph_msg_data_add_pagelist() Sasha Levin
2019-11-16 16:23   ` Ilya Dryomov
2019-11-25 14:06     ` Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 106/237] mISDN: Fix type of switch control variable in ctrl_teimanager Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 107/237] qlcnic: fix a return in qlcnic_dcb_get_capability() Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 108/237] net: ethernet: ti: cpsw: unsync mcast entries while switch promisc mode Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 113/237] net: socionext: Stop PHY before resetting netsec Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 123/237] net: ethernet: cadence: fix socket buffer corruption problem Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 124/237] bpf: devmap: fix wrong interface selection in notifier_call Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 125/237] bpf, btf: fix a missing check bug in btf_parse Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 127/237] sparc64: Rework xchg() definition to avoid warnings Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 134/237] macsec: update operstate when lower device changes Sasha Levin
2019-11-16 15:39 ` [PATCH AUTOSEL 4.19 135/237] macsec: let the administrator set UP state even if lowerdev is down Sasha Levin
2019-11-16 15:39 ` Sasha Levin [this message]
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 166/237] igb: shorten maximum PHC timecounter update interval Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 167/237] fm10k: ensure completer aborts are marked as non-fatal after a resume Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 168/237] net: hns3: bugfix for buffer not free problem during resetting Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 169/237] net: hns3: bugfix for reporting unknown vector0 interrupt repeatly problem Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 170/237] net: hns3: bugfix for is_valid_csq_clean_head() Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 171/237] net: hns3: bugfix for hclge_mdio_write and hclge_mdio_read Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 172/237] ntb_netdev: fix sleep time mismatch Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 183/237] net: do not abort bulk send on BQL status Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 186/237] openvswitch: fix linking without CONFIG_NF_CONNTRACK_LABELS Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 191/237] sock_diag: fix autoloading of the raw_diag module Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 192/237] net: bpfilter: fix iptables failure if bpfilter_umh is disabled Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 196/237] wil6210: fix debugfs memory access alignment Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 197/237] wil6210: fix L2 RX status handling Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 198/237] wil6210: fix RGF_CAF_ICR address for Talyn-MB Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 199/237] wil6210: fix locking in wmi_call Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 200/237] ath10k: snoc: fix unbalanced clock error handling Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 201/237] wlcore: Fix the return value in case of error in 'wlcore_vendor_cmd_smart_config_start()' Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 202/237] rtl8xxxu: Fix missing break in switch Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 203/237] brcmsmac: never log "tid x is not agg'able" by default Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 204/237] wireless: airo: potential buffer overflow in sprintf() Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 205/237] rtlwifi: rtl8192de: Fix misleading REG_MCUFWDL information Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 206/237] net: dsa: bcm_sf2: Turn on PHY to allow successful registration Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 218/237] vrf: mark skb for multicast or link-local as enslaved to VRF Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 221/237] net: bcmgenet: return correct value 'ret' from bcmgenet_power_down Sasha Levin
2019-11-16 15:40 ` [PATCH AUTOSEL 4.19 222/237] sock: Reset dst when changing sk_mark via setsockopt Sasha Levin
2019-11-16 15:41 ` [PATCH AUTOSEL 4.19 225/237] tools: bpftool: pass an argument to silence open_obj_pinned() Sasha Levin
2019-11-16 15:41 ` [PATCH AUTOSEL 4.19 226/237] cfg80211: Prevent regulatory restore during STA disconnect in concurrent interfaces Sasha Levin
2019-11-16 15:41 ` [PATCH AUTOSEL 4.19 236/237] ipv6: Fix handling of LLA with VRF and sockets bound to VRF Sasha Levin
2019-11-16 15:41 ` [PATCH AUTOSEL 4.19 237/237] cfg80211: call disconnect_wk when AP stops Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191116154113.7417-142-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liuhangbin@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=yinxu@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).