]> git.ipfire.org Git - people/arne_f/ipfire-3.x.git/blob - kernel/patches/linux-3.1-bridge-master-device-stuck-in-no-carrier-state-forever-when-in-user-stp-mode.patch
autoconf: updated to 2.69.
[people/arne_f/ipfire-3.x.git] / kernel / patches / linux-3.1-bridge-master-device-stuck-in-no-carrier-state-forever-when-in-user-stp-mode.patch
1 From b03b6dd58cef7d15b7c46a6729b83dd535ef08ab Mon Sep 17 00:00:00 2001
2 From: Vitalii Demianets <vitas@nppfactor.kiev.ua>
3 Date: Fri, 25 Nov 2011 00:16:37 +0000
4 Subject: [PATCH] bridge: master device stuck in no-carrier state forever when
5 in user-stp mode
6
7 When in user-stp mode, bridge master do not follow state of its slaves, so
8 after the following sequence of events it can stuck forever in no-carrier
9 state:
10 1) turn stp off
11 2) put all slaves down - master device will follow their state and also go in
12 no-carrier state
13 3) turn stp on with bridge-stp script returning 0 (go to the user-stp mode)
14 Now bridge master won't follow slaves' state and will never reach running
15 state.
16
17 This patch solves the problem by making user-stp and kernel-stp behavior
18 similar regarding master following slaves' states.
19
20 Signed-off-by: Vitalii Demianets <vitas@nppfactor.kiev.ua>
21 Acked-by: Stephen Hemminger <shemminger@vyatta.com>
22 Signed-off-by: David S. Miller <davem@davemloft.net>
23 ---
24 net/bridge/br_netlink.c | 6 ++++++
25 net/bridge/br_stp.c | 29 ++++++++++++++---------------
26 2 files changed, 20 insertions(+), 15 deletions(-)
27
28 diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
29 index e5f9ece3..a1daf82 100644
30 --- a/net/bridge/br_netlink.c
31 +++ b/net/bridge/br_netlink.c
32 @@ -18,6 +18,7 @@
33 #include <net/sock.h>
34
35 #include "br_private.h"
36 +#include "br_private_stp.h"
37
38 static inline size_t br_nlmsg_size(void)
39 {
40 @@ -188,6 +189,11 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
41
42 p->state = new_state;
43 br_log_state(p);
44 +
45 + spin_lock_bh(&p->br->lock);
46 + br_port_state_selection(p->br);
47 + spin_unlock_bh(&p->br->lock);
48 +
49 br_ifinfo_notify(RTM_NEWLINK, p);
50
51 return 0;
52 diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
53 index ad0a3f7..dd147d7 100644
54 --- a/net/bridge/br_stp.c
55 +++ b/net/bridge/br_stp.c
56 @@ -399,25 +399,24 @@ void br_port_state_selection(struct net_bridge *br)
57 struct net_bridge_port *p;
58 unsigned int liveports = 0;
59
60 - /* Don't change port states if userspace is handling STP */
61 - if (br->stp_enabled == BR_USER_STP)
62 - return;
63 -
64 list_for_each_entry(p, &br->port_list, list) {
65 if (p->state == BR_STATE_DISABLED)
66 continue;
67
68 - if (p->port_no == br->root_port) {
69 - p->config_pending = 0;
70 - p->topology_change_ack = 0;
71 - br_make_forwarding(p);
72 - } else if (br_is_designated_port(p)) {
73 - del_timer(&p->message_age_timer);
74 - br_make_forwarding(p);
75 - } else {
76 - p->config_pending = 0;
77 - p->topology_change_ack = 0;
78 - br_make_blocking(p);
79 + /* Don't change port states if userspace is handling STP */
80 + if (br->stp_enabled != BR_USER_STP) {
81 + if (p->port_no == br->root_port) {
82 + p->config_pending = 0;
83 + p->topology_change_ack = 0;
84 + br_make_forwarding(p);
85 + } else if (br_is_designated_port(p)) {
86 + del_timer(&p->message_age_timer);
87 + br_make_forwarding(p);
88 + } else {
89 + p->config_pending = 0;
90 + p->topology_change_ack = 0;
91 + br_make_blocking(p);
92 + }
93 }
94
95 if (p->state == BR_STATE_FORWARDING)
96 --
97 1.7.6.2
98