summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@c0d3.blue>2017-05-23 21:53:52 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-06-17 06:39:36 +0200
commit8d228758f90f234d1c5c6696960a5bd6a392c751 (patch)
tree1ca4d823d2dfffd75ee7cf5375898bd79c085586
parentee0cd47799dd63c38e3ae842be6693b53b315735 (diff)
ipv6: Fix IPv6 packet loss in scenarios involving roaming + snooping switches
[ Upstream commit a088d1d73a4bcfd7bc482f8d08375b9b665dc3e5 ] When for instance a mobile Linux device roams from one access point to another with both APs sharing the same broadcast domain and a multicast snooping switch in between: 1) (c) <~~~> (AP1) <--[SSW]--> (AP2) 2) (AP1) <--[SSW]--> (AP2) <~~~> (c) Then currently IPv6 multicast packets will get lost for (c) until an MLD Querier sends its next query message. The packet loss occurs because upon roaming the Linux host so far stayed silent regarding MLD and the snooping switch will therefore be unaware of the multicast topology change for a while. This patch fixes this by always resending MLD reports when an interface change happens, for instance from NO-CARRIER to CARRIER state. Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/ipv6/addrconf.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7090fef372cc..8cf3fc7c2932 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3211,9 +3211,15 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
}
if (idev) {
- if (idev->if_flags & IF_READY)
- /* device is already configured. */
+ if (idev->if_flags & IF_READY) {
+ /* device is already configured -
+ * but resend MLD reports, we might
+ * have roamed and need to update
+ * multicast snooping switches
+ */
+ ipv6_mc_up(idev);
break;
+ }
idev->if_flags |= IF_READY;
}