From: Ivan Vecera <hidden> Date: 2017-05-19 17:30:53
Current bridge code incorrectly handles starting/stopping of hello and
hold timers during STP enable/disable.
1. Timers are stopped in br_stp_start() during NO_STP->USER_STP
transition. The timers are already stopped in NO_STP state so
this is confusing no-op.
2. During USER_STP->NO_STP transition the timers are started. This
does not make sense and is confusion because the timer should not be
active in NO_STP state.
Cc: davem@davemloft.net
Cc: sashok@cumulusnetworks.com
Cc: stephen@networkplumber.org
Cc: bridge@lists.linux-foundation.org
Cc: lucien.xin@gmail.com
Cc: nikolay@cumulusnetworks.com
Signed-off-by: Ivan Vecera <redacted>
---
net/bridge/br_stp_if.c | 11 -----------
1 file changed, 11 deletions(-)
@@ -196,10 +189,6 @@ static void br_stp_stop(struct net_bridge *br)br_err(br,"failed to stop userspace STP (%d)\n",err);/* To start timers on any ports left in blocking */-mod_timer(&br->hello_timer,jiffies+br->hello_time);-list_for_each_entry(p,&br->port_list,list)-mod_timer(&p->hold_timer,-round_jiffies(jiffies+BR_HOLD_TIME));spin_lock_bh(&br->lock);br_port_state_selection(br);spin_unlock_bh(&br->lock);
From: Xin Long <lucien.xin@gmail.com> Date: 2017-05-19 17:35:26
On Sat, May 20, 2017 at 1:30 AM, Ivan Vecera [off-list ref] wrote:
Current bridge code incorrectly handles starting/stopping of hello and
hold timers during STP enable/disable.
1. Timers are stopped in br_stp_start() during NO_STP->USER_STP
transition. The timers are already stopped in NO_STP state so
this is confusing no-op.
2. During USER_STP->NO_STP transition the timers are started. This
does not make sense and is confusion because the timer should not be
active in NO_STP state.
Cc: davem@davemloft.net
Cc: sashok@cumulusnetworks.com
Cc: stephen@networkplumber.org
Cc: bridge@lists.linux-foundation.org
Cc: lucien.xin@gmail.com
Cc: nikolay@cumulusnetworks.com
Signed-off-by: Ivan Vecera <redacted>
@@ -196,10 +189,6 @@ static void br_stp_stop(struct net_bridge *br)br_err(br,"failed to stop userspace STP (%d)\n",err);/* To start timers on any ports left in blocking */-mod_timer(&br->hello_timer,jiffies+br->hello_time);-list_for_each_entry(p,&br->port_list,list)-mod_timer(&p->hold_timer,-round_jiffies(jiffies+BR_HOLD_TIME));spin_lock_bh(&br->lock);br_port_state_selection(br);spin_unlock_bh(&br->lock);--
From: Nikolay Aleksandrov <hidden> Date: 2017-05-19 20:12:49
On 5/19/17 8:30 PM, Ivan Vecera wrote:
Current bridge code incorrectly handles starting/stopping of hello and
hold timers during STP enable/disable.
1. Timers are stopped in br_stp_start() during NO_STP->USER_STP
transition. The timers are already stopped in NO_STP state so
this is confusing no-op.
2. During USER_STP->NO_STP transition the timers are started. This
does not make sense and is confusion because the timer should not be
active in NO_STP state.
Cc: davem@davemloft.net
Cc: sashok@cumulusnetworks.com
Cc: stephen@networkplumber.org
Cc: bridge@lists.linux-foundation.org
Cc: lucien.xin@gmail.com
Cc: nikolay@cumulusnetworks.com
Signed-off-by: Ivan Vecera <redacted>
---
net/bridge/br_stp_if.c | 11 -----------
1 file changed, 11 deletions(-)
LGTM, thanks!
Acked-by: Nikolay Aleksandrov <redacted>
From: Hangbin Liu <hidden> Date: 2017-05-20 05:57:38
On Fri, May 19, 2017 at 07:30:43PM +0200, Ivan Vecera wrote:
Current bridge code incorrectly handles starting/stopping of hello and
hold timers during STP enable/disable.
1. Timers are stopped in br_stp_start() during NO_STP->USER_STP
transition. The timers are already stopped in NO_STP state so
this is confusing no-op.
Hi Ivan,
Shouldn't we start hello timer in br_stp_start when NO_STP -> BR_KERNEL_STP ?
2. During USER_STP->NO_STP transition the timers are started. This
does not make sense and is confusion because the timer should not be
active in NO_STP state.
Yes, but what about BR_KERNEL_STP -> NO_STP in function br_stp_stop() ?
@@ -169,11 +168,6 @@ static void br_stp_start(struct net_bridge *br)if(!err){br->stp_enabled=BR_USER_STP;br_debug(br,"userspace STP started\n");--/* Stop hello and hold timers */-del_timer(&br->hello_timer);-list_for_each_entry(p,&br->port_list,list)-del_timer(&p->hold_timer);
I'm not sure if user space daemon will send bpdu or not? In comment
76b91c32dd86 ("bridge: stp: when using userspace stp stop kernel hello and
hold timers"). Nikolay said we should not handle it with BR_USER_STP.
@@ -196,10 +189,6 @@ static void br_stp_stop(struct net_bridge *br) br_err(br, "failed to stop userspace STP (%d)\n", err); /* To start timers on any ports left in blocking */- mod_timer(&br->hello_timer, jiffies + br->hello_time);- list_for_each_entry(p, &br->port_list, list)- mod_timer(&p->hold_timer,- round_jiffies(jiffies + BR_HOLD_TIME));
If we do not del hello_timer. after it expired in br_hello_timer_expired(),
Our state is br->dev->flags & IFF_UP and br->stp_enabled == NO_STP, it will
call mod_timer(&br->hello_timer, round_jiffies(jiffies + br->hello_time))
and we will keep sending bpdu message even after stp stoped.
@@ -183,6 +183,7 @@ static void br_stp_start(struct net_bridge *br)}else{br->stp_enabled=BR_KERNEL_STP;br_debug(br,"using kernel STP\n");+mod_timer(&br->hello_timer,jiffies+br->hello_time);/* To start timers on any ports left in blocking */br_port_state_selection(br);
@@ -202,7 +203,6 @@ static void br_stp_stop(struct net_bridge *br)br_err(br,"failed to stop userspace STP (%d)\n",err);/* To start timers on any ports left in blocking */-mod_timer(&br->hello_timer,jiffies+br->hello_time);list_for_each_entry(p,&br->port_list,list)mod_timer(&p->hold_timer,round_jiffies(jiffies+BR_HOLD_TIME));
From: Nikolay Aleksandrov <hidden> Date: 2017-05-20 06:55:14
On 5/20/17 8:57 AM, Hangbin Liu wrote:
On Fri, May 19, 2017 at 07:30:43PM +0200, Ivan Vecera wrote:
quoted
Current bridge code incorrectly handles starting/stopping of hello and
hold timers during STP enable/disable.
1. Timers are stopped in br_stp_start() during NO_STP->USER_STP
transition. The timers are already stopped in NO_STP state so
this is confusing no-op.
Hi Ivan,
Shouldn't we start hello timer in br_stp_start when NO_STP -> BR_KERNEL_STP ?
2. During USER_STP->NO_STP transition the timers are started. This
does not make sense and is confusion because the timer should not be
active in NO_STP state.
Yes, but what about BR_KERNEL_STP -> NO_STP in function br_stp_stop() ?
@@ -169,11 +168,6 @@ static void br_stp_start(struct net_bridge *br)if(!err){br->stp_enabled=BR_USER_STP;br_debug(br,"userspace STP started\n");--/* Stop hello and hold timers */-del_timer(&br->hello_timer);-list_for_each_entry(p,&br->port_list,list)-del_timer(&p->hold_timer);
I'm not sure if user space daemon will send bpdu or not? In comment
76b91c32dd86 ("bridge: stp: when using userspace stp stop kernel hello and
hold timers"). Nikolay said we should not handle it with BR_USER_STP >
@@ -196,10 +189,6 @@ static void br_stp_stop(struct net_bridge *br) br_err(br, "failed to stop userspace STP (%d)\n", err); /* To start timers on any ports left in blocking */- mod_timer(&br->hello_timer, jiffies + br->hello_time);- list_for_each_entry(p, &br->port_list, list)- mod_timer(&p->hold_timer,- round_jiffies(jiffies + BR_HOLD_TIME));
If we do not del hello_timer. after it expired in br_hello_timer_expired(),
Our state is br->dev->flags & IFF_UP and br->stp_enabled == NO_STP, it will
call mod_timer(&br->hello_timer, round_jiffies(jiffies + br->hello_time))
and we will keep sending bpdu message even after stp stoped.
@@ -183,6 +183,7 @@ static void br_stp_start(struct net_bridge *br)}else{br->stp_enabled=BR_KERNEL_STP;br_debug(br,"using kernel STP\n");+mod_timer(&br->hello_timer,jiffies+br->hello_time);/* To start timers on any ports left in blocking */br_port_state_selection(br);
@@ -202,7 +203,6 @@ static void br_stp_stop(struct net_bridge *br)br_err(br,"failed to stop userspace STP (%d)\n",err);/* To start timers on any ports left in blocking */-mod_timer(&br->hello_timer,jiffies+br->hello_time);list_for_each_entry(p,&br->port_list,list)mod_timer(&p->hold_timer,round_jiffies(jiffies+BR_HOLD_TIME));
From: Ivan Vecera <hidden> Date: 2017-05-20 07:06:16
2017-05-20 7:57 GMT+02:00 Hangbin Liu [off-list ref]:
On Fri, May 19, 2017 at 07:30:43PM +0200, Ivan Vecera wrote:
quoted
Current bridge code incorrectly handles starting/stopping of hello and
hold timers during STP enable/disable.
1. Timers are stopped in br_stp_start() during NO_STP->USER_STP
transition. The timers are already stopped in NO_STP state so
this is confusing no-op.
Hi Ivan,
Shouldn't we start hello timer in br_stp_start when NO_STP -> BR_KERNEL_STP ?
2. During USER_STP->NO_STP transition the timers are started. This
does not make sense and is confusion because the timer should not be
active in NO_STP state.
Yes, but what about BR_KERNEL_STP -> NO_STP in function br_stp_stop() ?
The timer is lazily stopped by itself in its handler... or not rearmed
respectively.
@@ -169,11 +168,6 @@ static void br_stp_start(struct net_bridge *br)if(!err){br->stp_enabled=BR_USER_STP;br_debug(br,"userspace STP started\n");--/* Stop hello and hold timers */-del_timer(&br->hello_timer);-list_for_each_entry(p,&br->port_list,list)-del_timer(&p->hold_timer);
I'm not sure if user space daemon will send bpdu or not? In comment
76b91c32dd86 ("bridge: stp: when using userspace stp stop kernel hello and
hold timers"). Nikolay said we should not handle it with BR_USER_STP.
@@ -196,10 +189,6 @@ static void br_stp_stop(struct net_bridge *br) br_err(br, "failed to stop userspace STP (%d)\n", err); /* To start timers on any ports left in blocking */- mod_timer(&br->hello_timer, jiffies + br->hello_time);- list_for_each_entry(p, &br->port_list, list)- mod_timer(&p->hold_timer,- round_jiffies(jiffies + BR_HOLD_TIME));
If we do not del hello_timer. after it expired in br_hello_timer_expired(),
Our state is br->dev->flags & IFF_UP and br->stp_enabled == NO_STP, it will
call mod_timer(&br->hello_timer, round_jiffies(jiffies + br->hello_time))
and we will keep sending bpdu message even after stp stoped.
@@ -183,6 +183,7 @@ static void br_stp_start(struct net_bridge *br)}else{br->stp_enabled=BR_KERNEL_STP;br_debug(br,"using kernel STP\n");+mod_timer(&br->hello_timer,jiffies+br->hello_time);/* To start timers on any ports left in blocking */br_port_state_selection(br);
@@ -202,7 +203,6 @@ static void br_stp_stop(struct net_bridge *br)br_err(br,"failed to stop userspace STP (%d)\n",err);/* To start timers on any ports left in blocking */-mod_timer(&br->hello_timer,jiffies+br->hello_time);list_for_each_entry(p,&br->port_list,list)mod_timer(&p->hold_timer,round_jiffies(jiffies+BR_HOLD_TIME));
From: Hangbin Liu <hidden> Date: 2017-05-20 07:48:01
On Sat, May 20, 2017 at 09:06:16AM +0200, Ivan Vecera wrote:
2017-05-20 7:57 GMT+02:00 Hangbin Liu [off-list ref]:
quoted
On Fri, May 19, 2017 at 07:30:43PM +0200, Ivan Vecera wrote:
quoted
Current bridge code incorrectly handles starting/stopping of hello and
hold timers during STP enable/disable.
1. Timers are stopped in br_stp_start() during NO_STP->USER_STP
transition. The timers are already stopped in NO_STP state so
this is confusing no-op.
Hi Ivan,
Shouldn't we start hello timer in br_stp_start when NO_STP -> BR_KERNEL_STP ?
Ah, sorry. My mistake. I only saw xin's patch and your v2 patch. So I mixed
them up and thought this is xin's V2 patch. That's why I wonder we didn't
start hello timer in br_stp_start...
Now I see your v1 patch with:
The patch is a follow-up for "bridge: start hello_timer when enabling
KERNEL_STP in br_stp_start" patch from Xin Long."
Sorry for mixed them up.
quoted
quoted
2. During USER_STP->NO_STP transition the timers are started. This
does not make sense and is confusion because the timer should not be
active in NO_STP state.
Yes, but what about BR_KERNEL_STP -> NO_STP in function br_stp_stop() ?
The timer is lazily stopped by itself in its handler... or not rearmed
respectively.
Yes, with xin's patch this timer will stoped by itself.
Thanks
Hangbin
From: David Miller <davem@davemloft.net> Date: 2017-05-22 18:41:32
From: Ivan Vecera <redacted>
Date: Fri, 19 May 2017 19:30:43 +0200
Current bridge code incorrectly handles starting/stopping of hello and
hold timers during STP enable/disable.
1. Timers are stopped in br_stp_start() during NO_STP->USER_STP
transition. The timers are already stopped in NO_STP state so
this is confusing no-op.
2. During USER_STP->NO_STP transition the timers are started. This
does not make sense and is confusion because the timer should not be
active in NO_STP state.
Cc: davem@davemloft.net
Cc: sashok@cumulusnetworks.com
Cc: stephen@networkplumber.org
Cc: bridge@lists.linux-foundation.org
Cc: lucien.xin@gmail.com
Cc: nikolay@cumulusnetworks.com
Signed-off-by: Ivan Vecera <redacted>