diff options
author | Vitalii Demianets <vitas@nppfactor.kiev.ua> | 2011-11-24 19:16:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-01 14:05:17 -0500 |
commit | b03b6dd58cef7d15b7c46a6729b83dd535ef08ab (patch) | |
tree | a193461397942346f330b782a200849feafa1991 /net/bridge/br_netlink.c | |
parent | efbc368dcc6426d5430b9b8eeda944cf2cb74b8c (diff) |
bridge: master device stuck in no-carrier state forever when in user-stp mode
When in user-stp mode, bridge master do not follow state of its slaves, so
after the following sequence of events it can stuck forever in no-carrier
state:
1) turn stp off
2) put all slaves down - master device will follow their state and also go in
no-carrier state
3) turn stp on with bridge-stp script returning 0 (go to the user-stp mode)
Now bridge master won't follow slaves' state and will never reach running
state.
This patch solves the problem by making user-stp and kernel-stp behavior
similar regarding master following slaves' states.
Signed-off-by: Vitalii Demianets <vitas@nppfactor.kiev.ua>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_netlink.c')
-rw-r--r-- | net/bridge/br_netlink.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index e5f9ece3c9a0..a1daf8227ed1 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <net/sock.h> | 18 | #include <net/sock.h> |
19 | 19 | ||
20 | #include "br_private.h" | 20 | #include "br_private.h" |
21 | #include "br_private_stp.h" | ||
21 | 22 | ||
22 | static inline size_t br_nlmsg_size(void) | 23 | static inline size_t br_nlmsg_size(void) |
23 | { | 24 | { |
@@ -188,6 +189,11 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
188 | 189 | ||
189 | p->state = new_state; | 190 | p->state = new_state; |
190 | br_log_state(p); | 191 | br_log_state(p); |
192 | |||
193 | spin_lock_bh(&p->br->lock); | ||
194 | br_port_state_selection(p->br); | ||
195 | spin_unlock_bh(&p->br->lock); | ||
196 | |||
191 | br_ifinfo_notify(RTM_NEWLINK, p); | 197 | br_ifinfo_notify(RTM_NEWLINK, p); |
192 | 198 | ||
193 | return 0; | 199 | return 0; |