diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index c08e02b67818..bca5ead3e973 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -409,7 +409,7 @@ void br_dev_setup(struct net_device *dev) br->bridge_max_age = br->max_age = 20 * HZ; br->bridge_hello_time = br->hello_time = 2 * HZ; br->bridge_forward_delay = br->forward_delay = 15 * HZ; - br->ageing_time = BR_DEFAULT_AGEING_TIME; + br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME; dev->max_mtu = ETH_MAX_MTU; br_netfilter_rtable_init(br); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index e2cd6d12a273..8ce621e8345c 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -300,10 +300,11 @@ struct net_bridge unsigned long max_age; unsigned long hello_time; unsigned long forward_delay; - unsigned long bridge_max_age; unsigned long ageing_time; + unsigned long bridge_max_age; unsigned long bridge_hello_time; unsigned long bridge_forward_delay; + unsigned long bridge_ageing_time; u8 group_addr[ETH_ALEN]; bool group_addr_set; diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index 8d7b4c7a1d54..71fd1a4e63cc 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c @@ -597,7 +597,11 @@ int br_set_ageing_time(struct net_bridge *br, clock_t ageing_time) if (err) return err; + spin_lock_bh(&br->lock); + br->bridge_ageing_time = t; br->ageing_time = t; + spin_unlock_bh(&br->lock); + mod_timer(&br->gc_timer, jiffies); return 0; @@ -606,6 +610,29 @@ int br_set_ageing_time(struct net_bridge *br, clock_t ageing_time) /* called under bridge lock */ void __br_set_topology_change(struct net_bridge *br, unsigned char val) { + unsigned long t; + int err; + + if (br->stp_enabled == BR_KERNEL_STP && br->topology_change != val) { + /* On topology change, set the bridge ageing time to twice the + * forward delay. Otherwise, restore its default ageing time. + */ + + if (val) { + t = 2 * br->forward_delay; + br_debug(br, "decreasing ageing time to %lu\n", t); + } else { + t = br->bridge_ageing_time; + br_debug(br, "restoring ageing time to %lu\n", t); + } + + err = __set_ageing_time(br->dev, t); + if (err) + br_warn(br, "error offloading ageing time\n"); + else + br->ageing_time = t; + } + br->topology_change = val; }