aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/bridge/br_input.c2
-rw-r--r--net/bridge/br_multicast.c16
-rw-r--r--net/bridge/br_private.h3
3 files changed, 9 insertions, 12 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 6f6d8e1b776f..88e4aa9cb1f9 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -80,7 +80,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
80 if (is_multicast_ether_addr(dest)) { 80 if (is_multicast_ether_addr(dest)) {
81 mdst = br_mdb_get(br, skb); 81 mdst = br_mdb_get(br, skb);
82 if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { 82 if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
83 if ((mdst && !hlist_unhashed(&mdst->mglist)) || 83 if ((mdst && mdst->mglist) ||
84 br_multicast_is_router(br)) 84 br_multicast_is_router(br))
85 skb2 = skb; 85 skb2 = skb;
86 br_multicast_forward(mdst, skb, skb2); 86 br_multicast_forward(mdst, skb, skb2);
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index c558274051eb..09d5c0987925 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -232,8 +232,7 @@ static void br_multicast_group_expired(unsigned long data)
232 if (!netif_running(br->dev) || timer_pending(&mp->timer)) 232 if (!netif_running(br->dev) || timer_pending(&mp->timer))
233 goto out; 233 goto out;
234 234
235 if (!hlist_unhashed(&mp->mglist)) 235 mp->mglist = false;
236 hlist_del_init(&mp->mglist);
237 236
238 if (mp->ports) 237 if (mp->ports)
239 goto out; 238 goto out;
@@ -276,7 +275,7 @@ static void br_multicast_del_pg(struct net_bridge *br,
276 del_timer(&p->query_timer); 275 del_timer(&p->query_timer);
277 call_rcu_bh(&p->rcu, br_multicast_free_pg); 276 call_rcu_bh(&p->rcu, br_multicast_free_pg);
278 277
279 if (!mp->ports && hlist_unhashed(&mp->mglist) && 278 if (!mp->ports && !mp->mglist &&
280 netif_running(br->dev)) 279 netif_running(br->dev))
281 mod_timer(&mp->timer, jiffies); 280 mod_timer(&mp->timer, jiffies);
282 281
@@ -528,7 +527,7 @@ static void br_multicast_group_query_expired(unsigned long data)
528 struct net_bridge *br = mp->br; 527 struct net_bridge *br = mp->br;
529 528
530 spin_lock(&br->multicast_lock); 529 spin_lock(&br->multicast_lock);
531 if (!netif_running(br->dev) || hlist_unhashed(&mp->mglist) || 530 if (!netif_running(br->dev) || !mp->mglist ||
532 mp->queries_sent >= br->multicast_last_member_count) 531 mp->queries_sent >= br->multicast_last_member_count)
533 goto out; 532 goto out;
534 533
@@ -719,8 +718,7 @@ static int br_multicast_add_group(struct net_bridge *br,
719 goto err; 718 goto err;
720 719
721 if (!port) { 720 if (!port) {
722 if (hlist_unhashed(&mp->mglist)) 721 mp->mglist = true;
723 hlist_add_head(&mp->mglist, &br->mglist);
724 mod_timer(&mp->timer, now + br->multicast_membership_interval); 722 mod_timer(&mp->timer, now + br->multicast_membership_interval);
725 goto out; 723 goto out;
726 } 724 }
@@ -1166,7 +1164,7 @@ static int br_ip4_multicast_query(struct net_bridge *br,
1166 1164
1167 max_delay *= br->multicast_last_member_count; 1165 max_delay *= br->multicast_last_member_count;
1168 1166
1169 if (!hlist_unhashed(&mp->mglist) && 1167 if (mp->mglist &&
1170 (timer_pending(&mp->timer) ? 1168 (timer_pending(&mp->timer) ?
1171 time_after(mp->timer.expires, now + max_delay) : 1169 time_after(mp->timer.expires, now + max_delay) :
1172 try_to_del_timer_sync(&mp->timer) >= 0)) 1170 try_to_del_timer_sync(&mp->timer) >= 0))
@@ -1237,7 +1235,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
1237 goto out; 1235 goto out;
1238 1236
1239 max_delay *= br->multicast_last_member_count; 1237 max_delay *= br->multicast_last_member_count;
1240 if (!hlist_unhashed(&mp->mglist) && 1238 if (mp->mglist &&
1241 (timer_pending(&mp->timer) ? 1239 (timer_pending(&mp->timer) ?
1242 time_after(mp->timer.expires, now + max_delay) : 1240 time_after(mp->timer.expires, now + max_delay) :
1243 try_to_del_timer_sync(&mp->timer) >= 0)) 1241 try_to_del_timer_sync(&mp->timer) >= 0))
@@ -1284,7 +1282,7 @@ static void br_multicast_leave_group(struct net_bridge *br,
1284 br->multicast_last_member_interval; 1282 br->multicast_last_member_interval;
1285 1283
1286 if (!port) { 1284 if (!port) {
1287 if (!hlist_unhashed(&mp->mglist) && 1285 if (mp->mglist &&
1288 (timer_pending(&mp->timer) ? 1286 (timer_pending(&mp->timer) ?
1289 time_after(mp->timer.expires, time) : 1287 time_after(mp->timer.expires, time) :
1290 try_to_del_timer_sync(&mp->timer) >= 0)) { 1288 try_to_del_timer_sync(&mp->timer) >= 0)) {
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 84aac7734bfc..4e1b620b6be6 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -84,13 +84,13 @@ struct net_bridge_port_group {
84struct net_bridge_mdb_entry 84struct net_bridge_mdb_entry
85{ 85{
86 struct hlist_node hlist[2]; 86 struct hlist_node hlist[2];
87 struct hlist_node mglist;
88 struct net_bridge *br; 87 struct net_bridge *br;
89 struct net_bridge_port_group __rcu *ports; 88 struct net_bridge_port_group __rcu *ports;
90 struct rcu_head rcu; 89 struct rcu_head rcu;
91 struct timer_list timer; 90 struct timer_list timer;
92 struct timer_list query_timer; 91 struct timer_list query_timer;
93 struct br_ip addr; 92 struct br_ip addr;
93 bool mglist;
94 u32 queries_sent; 94 u32 queries_sent;
95}; 95};
96 96
@@ -238,7 +238,6 @@ struct net_bridge
238 spinlock_t multicast_lock; 238 spinlock_t multicast_lock;
239 struct net_bridge_mdb_htable __rcu *mdb; 239 struct net_bridge_mdb_htable __rcu *mdb;
240 struct hlist_head router_list; 240 struct hlist_head router_list;
241 struct hlist_head mglist;
242 241
243 struct timer_list multicast_router_timer; 242 struct timer_list multicast_router_timer;
244 struct timer_list multicast_querier_timer; 243 struct timer_list multicast_querier_timer;