[ovs-dev] [PATCH v2 15/17] rstp: Fix global transitions.

Jarno Rajahalme jrajahalme at nicira.com
Wed Nov 19 18:57:26 UTC 2014


Acked-by: Jarno Rajahalme <jrajahalme at nicira.com>

& merged to master,

  Jarno

On Nov 14, 2014, at 9:26 AM, Daniele Venturino <daniele.venturino at m3s.it> wrote:

> Global transitions are highest priority transitions. When the condition
> associated with a global transition is met, it supersedes all other exit
> conditions including UCT.
> 
> Extracted from 802.1D-2004 standard (17.16):
> 
> A transition that is global in nature (i.e., a transition that occurs from any
> of the possible states if the condition attached to the arrow is met) is
> denoted by an open arrow, i.e., no specific state is identified as the origin
> of the transition. When the condition associated with a global transition is
> met, it supersedes all other exit conditions including UCT. The special global
> condition BEGIN supersedes all other global conditions, and once asserted
> remains asserted until all state blocks have executed to the point that
> variable assignments and other consequences of their execution remain
> unchanged.
> 
> Signed-off-by: Daniele Venturino <daniele.venturino at m3s.it>
> ---
> lib/rstp-state-machines.c | 265 ++++++++++++++++++++++++++++++++--------------
> 1 file changed, 188 insertions(+), 77 deletions(-)
> 
> diff --git a/lib/rstp-state-machines.c b/lib/rstp-state-machines.c
> index ac66488..fda8a72 100644
> --- a/lib/rstp-state-machines.c
> +++ b/lib/rstp-state-machines.c
> @@ -518,7 +518,11 @@ port_receive_sm(struct rstp_port *p)
>         p->port_receive_sm_state = PORT_RECEIVE_SM_DISCARD;
>         /* no break */
>     case PORT_RECEIVE_SM_DISCARD:
> -        if (p->rcvd_bpdu && p->port_enabled) {
> +        if ((p->rcvd_bpdu || (p->edge_delay_while != r->migrate_time))
> +                && !p->port_enabled) {
> +            /* Global transition. */
> +            p->port_receive_sm_state = PORT_RECEIVE_SM_DISCARD_EXEC;
> +        } else if (p->rcvd_bpdu && p->port_enabled) {
>             p->port_receive_sm_state = PORT_RECEIVE_SM_RECEIVE_EXEC;
>         }
>         break;
> @@ -530,7 +534,11 @@ port_receive_sm(struct rstp_port *p)
>         p->port_receive_sm_state = PORT_RECEIVE_SM_RECEIVE;
>         /* no break */
>     case PORT_RECEIVE_SM_RECEIVE:
> -        if (p->rcvd_bpdu && p->port_enabled && !p->rcvd_msg) {
> +        if ((p->rcvd_bpdu || (p->edge_delay_while != r->migrate_time))
> +                && !p->port_enabled) {
> +            /* Global transition. */
> +            p->port_receive_sm_state = PORT_RECEIVE_SM_DISCARD_EXEC;
> +        } else if (p->rcvd_bpdu && p->port_enabled && !p->rcvd_msg) {
>             p->port_receive_sm_state = PORT_RECEIVE_SM_RECEIVE_EXEC;
>         }
>         break;
> @@ -1127,12 +1135,11 @@ port_information_sm(struct rstp_port *p)
>     old_state = p->port_information_sm_state;
>     r = p->rstp;
> 
> -    if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> -        p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> -    }
>     switch (p->port_information_sm_state) {
>     case PORT_INFORMATION_SM_INIT:
> -        if (r->begin) {
> +        if (r->begin
> +            || (!p->port_enabled && p->info_is != INFO_IS_DISABLED)) {
> +            /* Global transition. */
>             p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
>         }
>         break;
> @@ -1146,7 +1153,10 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED;
>         /* no break */
>     case PORT_INFORMATION_SM_DISABLED:
> -        if (p->port_enabled) {
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else if (p->port_enabled) {
>             p->port_information_sm_state = PORT_INFORMATION_SM_AGED_EXEC;
>         } else if (p->rcvd_msg) {
>             p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> @@ -1159,7 +1169,10 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_AGED;
>         /* no break */
>     case PORT_INFORMATION_SM_AGED:
> -        if (p->selected && p->updt_info) {
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else if (p->selected && p->updt_info) {
>             p->port_information_sm_state = PORT_INFORMATION_SM_UPDATE_EXEC;
>         }
>         break;
> @@ -1183,13 +1196,21 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_UPDATE;
>         /* no break */
>     case PORT_INFORMATION_SM_UPDATE:
> -        p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else {
> +            p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        }
>         break;
>     case PORT_INFORMATION_SM_CURRENT_EXEC:
>         p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT;
>         /* no break */
>     case PORT_INFORMATION_SM_CURRENT:
> -        if (p->rcvd_msg && !p->updt_info) {
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else if (p->rcvd_msg && !p->updt_info) {
>             p->port_information_sm_state = PORT_INFORMATION_SM_RECEIVE_EXEC;
>         } else if (p->selected && p->updt_info) {
>             p->port_information_sm_state = PORT_INFORMATION_SM_UPDATE_EXEC;
> @@ -1204,29 +1225,34 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_RECEIVE;
>         /* no break */
>     case PORT_INFORMATION_SM_RECEIVE:
> -        switch (p->rcvd_info) {
> -        case SUPERIOR_DESIGNATED_INFO:
> -            p->port_information_sm_state =
> -                PORT_INFORMATION_SM_SUPERIOR_DESIGNATED_EXEC;
> -            break;
> -        case REPEATED_DESIGNATED_INFO:
> -            p->port_information_sm_state =
> -                PORT_INFORMATION_SM_REPEATED_DESIGNATED_EXEC;
> -            break;
> -        case INFERIOR_DESIGNATED_INFO:
> -            p->port_information_sm_state =
> -                PORT_INFORMATION_SM_INFERIOR_DESIGNATED_EXEC;
> -            break;
> -        case INFERIOR_ROOT_ALTERNATE_INFO:
> -            p->port_information_sm_state =
> -                PORT_INFORMATION_SM_NOT_DESIGNATED_EXEC;
> -            break;
> -        case OTHER_INFO:
> -            p->port_information_sm_state = PORT_INFORMATION_SM_OTHER_EXEC;
> -            break;
> -        default:
> -            OVS_NOT_REACHED();
> -            /* no break */
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else {
> +            switch (p->rcvd_info) {
> +            case SUPERIOR_DESIGNATED_INFO:
> +                p->port_information_sm_state =
> +                    PORT_INFORMATION_SM_SUPERIOR_DESIGNATED_EXEC;
> +                break;
> +            case REPEATED_DESIGNATED_INFO:
> +                p->port_information_sm_state =
> +                    PORT_INFORMATION_SM_REPEATED_DESIGNATED_EXEC;
> +                break;
> +            case INFERIOR_DESIGNATED_INFO:
> +                p->port_information_sm_state =
> +                    PORT_INFORMATION_SM_INFERIOR_DESIGNATED_EXEC;
> +                break;
> +            case INFERIOR_ROOT_ALTERNATE_INFO:
> +                p->port_information_sm_state =
> +                    PORT_INFORMATION_SM_NOT_DESIGNATED_EXEC;
> +                break;
> +            case OTHER_INFO:
> +                p->port_information_sm_state = PORT_INFORMATION_SM_OTHER_EXEC;
> +                break;
> +            default:
> +                OVS_NOT_REACHED();
> +                /* no break */
> +            }
>         }
>         break;
>     case PORT_INFORMATION_SM_OTHER_EXEC:
> @@ -1234,7 +1260,12 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_OTHER;
>         /* no break */
>     case PORT_INFORMATION_SM_OTHER:
> -        p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else {
> +            p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        }
>         break;
>     case PORT_INFORMATION_SM_NOT_DESIGNATED_EXEC:
>         record_agreement(p);
> @@ -1243,7 +1274,12 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_NOT_DESIGNATED;
>         /* no break */
>     case PORT_INFORMATION_SM_NOT_DESIGNATED:
> -        p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else {
> +            p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        }
>         break;
>     case PORT_INFORMATION_SM_INFERIOR_DESIGNATED_EXEC:
>         record_dispute(p);
> @@ -1251,7 +1287,12 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_INFERIOR_DESIGNATED;
>         /* no break */
>     case PORT_INFORMATION_SM_INFERIOR_DESIGNATED:
> -        p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else {
> +            p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        }
>         break;
>     case PORT_INFORMATION_SM_REPEATED_DESIGNATED_EXEC:
>         record_proposal(p);
> @@ -1261,7 +1302,12 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_REPEATED_DESIGNATED;
>         /* no break */
>     case PORT_INFORMATION_SM_REPEATED_DESIGNATED:
> -        p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else {
> +            p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        }
>         break;
>     case PORT_INFORMATION_SM_SUPERIOR_DESIGNATED_EXEC:
>         p->agreed = p->proposing = false;
> @@ -1279,7 +1325,12 @@ port_information_sm(struct rstp_port *p)
>         p->port_information_sm_state = PORT_INFORMATION_SM_SUPERIOR_DESIGNATED;
>         /* no break */
>     case PORT_INFORMATION_SM_SUPERIOR_DESIGNATED:
> -        p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        if (!p->port_enabled && p->info_is != INFO_IS_DISABLED) {
> +            /* Global transition. */
> +            p->port_information_sm_state = PORT_INFORMATION_SM_DISABLED_EXEC;
> +        } else {
> +            p->port_information_sm_state = PORT_INFORMATION_SM_CURRENT_EXEC;
> +        }
>         break;
>     default:
>         OVS_NOT_REACHED();
> @@ -1465,7 +1516,7 @@ port_role_transition_sm(struct rstp_port *p)
>         /* no break */
>     case PORT_ROLE_TRANSITION_SM_DISABLE_PORT:
>         if (check_selected_role_change(p, ROLE_DISABLED)) {
> -            break;
> +            /* Global transition. */
>         } else if (p->selected && !p->updt_info && !p->learning
>                    && !p->forwarding) {
>             p->port_role_transition_sm_state =
> @@ -1482,7 +1533,7 @@ port_role_transition_sm(struct rstp_port *p)
>         /* no break */
>     case PORT_ROLE_TRANSITION_SM_DISABLED_PORT:
>         if (check_selected_role_change(p, ROLE_DISABLED)) {
> -            break;
> +            /* Global transition. */
>         } else if (p->selected && !p->updt_info
>                    && (p->fd_while != p->designated_times.max_age || p->sync
>                        || p->re_root || !p->synced)) {
> @@ -1497,7 +1548,7 @@ port_role_transition_sm(struct rstp_port *p)
>         /* no break */
>     case PORT_ROLE_TRANSITION_SM_ROOT_PORT:
>         if (check_selected_role_change(p, ROLE_ROOT)) {
> -            break;
> +            /* Global transition. */
>         } else if (p->selected && !p->updt_info) {
>             if (p->rr_while != p->designated_times.forward_delay) {
>                 p->port_role_transition_sm_state =
> @@ -1536,38 +1587,62 @@ port_role_transition_sm(struct rstp_port *p)
>         }
>     break;
>     case PORT_ROLE_TRANSITION_SM_REROOT_EXEC:
> -        set_re_root_tree(p);
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ROOT)) {
> +            /* Global transition. */
> +        } else {
> +            set_re_root_tree(p);
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_ROOT_AGREED_EXEC:
> -        p->proposed = p->sync = false;
> -        p->agree = p->new_info = true;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ROOT)) {
> +            /* Global transition. */
> +        } else {
> +            p->proposed = p->sync = false;
> +            p->agree = p->new_info = true;
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_ROOT_PROPOSED_EXEC:
>         set_sync_tree(p);
>         p->proposed = false;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ROOT)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_ROOT_FORWARD_EXEC:
>         p->fd_while = 0;
>         p->forward = true;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ROOT)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_ROOT_LEARN_EXEC:
>         p->fd_while = forward_delay(p);
>         p->learn = true;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ROOT)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_REROOTED_EXEC:
>         p->re_root = false;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ROOT)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC:
>         p->role = ROLE_DESIGNATED;
> @@ -1576,7 +1651,7 @@ port_role_transition_sm(struct rstp_port *p)
>         /* no break */
>     case PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT:
>         if (check_selected_role_change(p, ROLE_DESIGNATED)) {
> -            break;
> +            /* Global transition. */
>         } else if (p->selected && !p->updt_info) {
>             if (((p->sync && !p->synced)
>                  || (p->re_root && p->rr_while != 0) || p->disputed)
> @@ -1611,41 +1686,65 @@ port_role_transition_sm(struct rstp_port *p)
>         break;
>     case PORT_ROLE_TRANSITION_SM_DESIGNATED_RETIRED_EXEC:
>         p->re_root = false;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_DESIGNATED)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_DESIGNATED_SYNCED_EXEC:
>         p->rr_while = 0;
>         p->synced = true;
>         p->sync = false;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_DESIGNATED)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_DESIGNATED_PROPOSE_EXEC:
>         p->proposing = true;
>         p->edge_delay_while = edge_delay(p);
>         p->new_info = true;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_DESIGNATED)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_DESIGNATED_FORWARD_EXEC:
>         p->forward = true;
>         p->fd_while = 0;
>         p->agreed = p->send_rstp;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_DESIGNATED)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_DESIGNATED_LEARN_EXEC:
>         p->learn = true;
>         p->fd_while = forward_delay(p);
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_DESIGNATED)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_DESIGNATED_DISCARD_EXEC:
>         p->learn = p->forward = p->disputed = false;
>         p->fd_while = forward_delay(p);
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_DESIGNATED)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT_EXEC:
>         p->fd_while = p->designated_times.forward_delay;
> @@ -1657,7 +1756,7 @@ port_role_transition_sm(struct rstp_port *p)
>         /* no break */
>     case PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT:
>         if (check_selected_role_change(p, ROLE_ALTERNATE)) {
> -            break;
> +            /* Global transition. */
>         } else if (p->selected && !p->updt_info) {
>             if (p->rb_while != 2 * p->designated_times.hello_time
>                 && p->role == ROLE_BACKUP) {
> @@ -1681,14 +1780,22 @@ port_role_transition_sm(struct rstp_port *p)
>         p->proposed = false;
>         p->agree = true;
>         p->new_info = true;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ALTERNATE)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_ALTERNATE_PROPOSED_EXEC:
>         set_sync_tree(p);
>         p->proposed = false;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ALTERNATE)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT_EXEC;
> +        }
>         break;
>     case PORT_ROLE_TRANSITION_SM_BLOCK_PORT_EXEC:
>         p->role = p->selected_role;
> @@ -1697,7 +1804,7 @@ port_role_transition_sm(struct rstp_port *p)
>         /* no break */
>     case PORT_ROLE_TRANSITION_SM_BLOCK_PORT:
>         if (check_selected_role_change(p, ROLE_ALTERNATE)) {
> -            break;
> +            /* Global transition. */
>         } else if (p->selected && !p->updt_info && !p->learning &&
>                    !p->forwarding) {
>             p->port_role_transition_sm_state =
> @@ -1706,8 +1813,12 @@ port_role_transition_sm(struct rstp_port *p)
>         break;
>     case PORT_ROLE_TRANSITION_SM_BACKUP_PORT_EXEC:
>         p->rb_while = 2 * p->designated_times.hello_time;
> -        p->port_role_transition_sm_state =
> -            PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT_EXEC;
> +        if (check_selected_role_change(p, ROLE_ALTERNATE)) {
> +            /* Global transition. */
> +        } else {
> +            p->port_role_transition_sm_state =
> +                PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT_EXEC;
> +        }
>         break;
>     default:
>         OVS_NOT_REACHED();
> -- 
> 1.8.1.2
> 




More information about the dev mailing list