aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_multicast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r--net/bridge/br_multicast.c61
1 files changed, 56 insertions, 5 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 674224b6729d..c7a1095ed84a 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -656,6 +656,15 @@ void br_multicast_del_port(struct net_bridge_port *port)
656 del_timer_sync(&port->multicast_router_timer); 656 del_timer_sync(&port->multicast_router_timer);
657} 657}
658 658
659static void __br_multicast_enable_port(struct net_bridge_port *port)
660{
661 port->multicast_startup_queries_sent = 0;
662
663 if (try_to_del_timer_sync(&port->multicast_query_timer) >= 0 ||
664 del_timer(&port->multicast_query_timer))
665 mod_timer(&port->multicast_query_timer, jiffies);
666}
667
659void br_multicast_enable_port(struct net_bridge_port *port) 668void br_multicast_enable_port(struct net_bridge_port *port)
660{ 669{
661 struct net_bridge *br = port->br; 670 struct net_bridge *br = port->br;
@@ -664,11 +673,7 @@ void br_multicast_enable_port(struct net_bridge_port *port)
664 if (br->multicast_disabled || !netif_running(br->dev)) 673 if (br->multicast_disabled || !netif_running(br->dev))
665 goto out; 674 goto out;
666 675
667 port->multicast_startup_queries_sent = 0; 676 __br_multicast_enable_port(port);
668
669 if (try_to_del_timer_sync(&port->multicast_query_timer) >= 0 ||
670 del_timer(&port->multicast_query_timer))
671 mod_timer(&port->multicast_query_timer, jiffies);
672 677
673out: 678out:
674 spin_unlock(&br->multicast_lock); 679 spin_unlock(&br->multicast_lock);
@@ -1210,3 +1215,49 @@ unlock:
1210 1215
1211 return err; 1216 return err;
1212} 1217}
1218
1219int br_multicast_toggle(struct net_bridge *br, unsigned long val)
1220{
1221 struct net_bridge_port *port;
1222 int err = -ENOENT;
1223
1224 spin_lock(&br->multicast_lock);
1225 if (!netif_running(br->dev))
1226 goto unlock;
1227
1228 err = 0;
1229 if (br->multicast_disabled == !val)
1230 goto unlock;
1231
1232 br->multicast_disabled = !val;
1233 if (br->multicast_disabled)
1234 goto unlock;
1235
1236 if (br->mdb) {
1237 if (br->mdb->old) {
1238 err = -EEXIST;
1239rollback:
1240 br->multicast_disabled = !!val;
1241 goto unlock;
1242 }
1243
1244 err = br_mdb_rehash(&br->mdb, br->mdb->max,
1245 br->hash_elasticity);
1246 if (err)
1247 goto rollback;
1248 }
1249
1250 br_multicast_open(br);
1251 list_for_each_entry(port, &br->port_list, list) {
1252 if (port->state == BR_STATE_DISABLED ||
1253 port->state == BR_STATE_BLOCKING)
1254 continue;
1255
1256 __br_multicast_enable_port(port);
1257 }
1258
1259unlock:
1260 spin_unlock(&br->multicast_lock);
1261
1262 return err;
1263}