]>
Commit | Line | Data |
---|---|---|
3cd4ea5b GKH |
1 | From 802d2fd9b43a5cf7cafca72683c7fb0458b6cab2 Mon Sep 17 00:00:00 2001 |
2 | From: Veaceslav Falico <vfalico@redhat.com> | |
3 | Date: Mon, 23 May 2011 23:15:05 +0000 | |
4 | Subject: igmp: call ip_mc_clear_src() only when we have no users of ip_mc_list | |
5 | ||
6 | ||
7 | From: Veaceslav Falico <vfalico@redhat.com> | |
8 | ||
9 | [ Upstream commit 24cf3af3fed5edcf90bc2a0ed181e6ce1513d2dc ] | |
10 | ||
11 | In igmp_group_dropped() we call ip_mc_clear_src(), which resets the number | |
12 | of source filters per mulitcast. However, igmp_group_dropped() is also | |
13 | called on NETDEV_DOWN, NETDEV_PRE_TYPE_CHANGE and NETDEV_UNREGISTER, which | |
14 | means that the group might get added back on NETDEV_UP, NETDEV_REGISTER and | |
15 | NETDEV_POST_TYPE_CHANGE respectively, leaving us with broken source | |
16 | filters. | |
17 | ||
18 | To fix that, we must clear the source filters only when there are no users | |
19 | in the ip_mc_list, i.e. in ip_mc_dec_group() and on device destroy. | |
20 | ||
21 | Acked-by: David L Stevens <dlstevens@us.ibm.com> | |
22 | Signed-off-by: Veaceslav Falico <vfalico@redhat.com> | |
23 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
24 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
25 | --- | |
26 | net/ipv4/igmp.c | 10 +++++----- | |
27 | 1 file changed, 5 insertions(+), 5 deletions(-) | |
28 | ||
29 | --- a/net/ipv4/igmp.c | |
30 | +++ b/net/ipv4/igmp.c | |
31 | @@ -1172,20 +1172,18 @@ static void igmp_group_dropped(struct ip | |
32 | ||
33 | if (!in_dev->dead) { | |
34 | if (IGMP_V1_SEEN(in_dev)) | |
35 | - goto done; | |
36 | + return; | |
37 | if (IGMP_V2_SEEN(in_dev)) { | |
38 | if (reporter) | |
39 | igmp_send_report(in_dev, im, IGMP_HOST_LEAVE_MESSAGE); | |
40 | - goto done; | |
41 | + return; | |
42 | } | |
43 | /* IGMPv3 */ | |
44 | igmpv3_add_delrec(in_dev, im); | |
45 | ||
46 | igmp_ifc_event(in_dev); | |
47 | } | |
48 | -done: | |
49 | #endif | |
50 | - ip_mc_clear_src(im); | |
51 | } | |
52 | ||
53 | static void igmp_group_added(struct ip_mc_list *im) | |
54 | @@ -1322,6 +1320,7 @@ void ip_mc_dec_group(struct in_device *i | |
55 | *ip = i->next_rcu; | |
56 | in_dev->mc_count--; | |
57 | igmp_group_dropped(i); | |
58 | + ip_mc_clear_src(i); | |
59 | ||
60 | if (!in_dev->dead) | |
61 | ip_rt_multicast_event(in_dev); | |
62 | @@ -1431,7 +1430,8 @@ void ip_mc_destroy_dev(struct in_device | |
63 | in_dev->mc_list = i->next_rcu; | |
64 | in_dev->mc_count--; | |
65 | ||
66 | - igmp_group_dropped(i); | |
67 | + /* We've dropped the groups in ip_mc_down already */ | |
68 | + ip_mc_clear_src(i); | |
69 | ip_ma_put(i); | |
70 | } | |
71 | } |