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_stp.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_stp.c')
-rw-r--r-- | net/bridge/br_stp.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index ad0a3f7cf6cc..dd147d78a588 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
@@ -399,25 +399,24 @@ void br_port_state_selection(struct net_bridge *br) | |||
399 | struct net_bridge_port *p; | 399 | struct net_bridge_port *p; |
400 | unsigned int liveports = 0; | 400 | unsigned int liveports = 0; |
401 | 401 | ||
402 | /* Don't change port states if userspace is handling STP */ | ||
403 | if (br->stp_enabled == BR_USER_STP) | ||
404 | return; | ||
405 | |||
406 | list_for_each_entry(p, &br->port_list, list) { | 402 | list_for_each_entry(p, &br->port_list, list) { |
407 | if (p->state == BR_STATE_DISABLED) | 403 | if (p->state == BR_STATE_DISABLED) |
408 | continue; | 404 | continue; |
409 | 405 | ||
410 | if (p->port_no == br->root_port) { | 406 | /* Don't change port states if userspace is handling STP */ |
411 | p->config_pending = 0; | 407 | if (br->stp_enabled != BR_USER_STP) { |
412 | p->topology_change_ack = 0; | 408 | if (p->port_no == br->root_port) { |
413 | br_make_forwarding(p); | 409 | p->config_pending = 0; |
414 | } else if (br_is_designated_port(p)) { | 410 | p->topology_change_ack = 0; |
415 | del_timer(&p->message_age_timer); | 411 | br_make_forwarding(p); |
416 | br_make_forwarding(p); | 412 | } else if (br_is_designated_port(p)) { |
417 | } else { | 413 | del_timer(&p->message_age_timer); |
418 | p->config_pending = 0; | 414 | br_make_forwarding(p); |
419 | p->topology_change_ack = 0; | 415 | } else { |
420 | br_make_blocking(p); | 416 | p->config_pending = 0; |
417 | p->topology_change_ack = 0; | ||
418 | br_make_blocking(p); | ||
419 | } | ||
421 | } | 420 | } |
422 | 421 | ||
423 | if (p->state == BR_STATE_FORWARDING) | 422 | if (p->state == BR_STATE_FORWARDING) |