summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorHangbin Liu <liuhangbin@gmail.com>2018-07-20 14:04:27 +0800
committerBen Hutchings <ben@decadent.org.uk>2018-11-20 18:05:46 +0000
commit841092b44ffdb5c82e71ec2c4c7507a53b52220b (patch)
treef6b78f10fdcb4529660b21fe7eb2f18962f0e3eb /net/ipv4
parent7113a9af08c596c62e819857c9f9a39f7de0403e (diff)
downloadlinux-stable-841092b44ffdb5c82e71ec2c4c7507a53b52220b.tar.gz
linux-stable-841092b44ffdb5c82e71ec2c4c7507a53b52220b.tar.bz2
linux-stable-841092b44ffdb5c82e71ec2c4c7507a53b52220b.zip
multicast: do not restore deleted record source filter mode to new one
commit 08d3ffcc0cfaba36f6b86fd568cc3bc773061fa6 upstream. There are two scenarios that we will restore deleted records. The first is when device down and up(or unmap/remap). In this scenario the new filter mode is same with previous one. Because we get it from in_dev->mc_list and we do not touch it during device down and up. The other scenario is when a new socket join a group which was just delete and not finish sending status reports. In this scenario, we should use the current filter mode instead of restore old one. Here are 4 cases in total. old_socket new_socket before_fix after_fix IN(A) IN(A) ALLOW(A) ALLOW(A) IN(A) EX( ) TO_IN( ) TO_EX( ) EX( ) IN(A) TO_EX( ) ALLOW(A) EX( ) EX( ) TO_EX( ) TO_EX( ) Fixes: 24803f38a5c0b (igmp: do not remove igmp souce list info when set link down) Fixes: 1666d49e1d416 (mld: do not remove mld souce list info when set link down) Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/igmp.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 337c333f64ae..08dfaeac1b08 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1159,8 +1159,7 @@ static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list *im)
if (pmc) {
im->interface = pmc->interface;
im->crcount = in_dev->mr_qrv ?: IGMP_Unsolicited_Report_Count;
- im->sfmode = pmc->sfmode;
- if (pmc->sfmode == MCAST_INCLUDE) {
+ if (im->sfmode == MCAST_INCLUDE) {
im->tomb = pmc->tomb;
im->sources = pmc->sources;
for (psf = im->sources; psf; psf = psf->sf_next)