]> git.ipfire.org Git - people/ms/rstp.git/blob - rstplib/sttrans.c
9174d762cbdb1af98bb1a33ac5ab5d9d7f31b479
[people/ms/rstp.git] / rstplib / sttrans.c
1 /************************************************************************
2 * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
3 * Copyright (C) 2001-2003 Optical Access
4 * Author: Alex Rozin
5 *
6 * This file is part of RSTP library.
7 *
8 * RSTP library is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by the
10 * Free Software Foundation; version 2.1
11 *
12 * RSTP library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with RSTP library; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 **********************************************************************/
22
23 /* Port State Transition state machine : 17.24 */
24
25 #include "base.h"
26 #include "stpm.h"
27 #include "stp_to.h"
28
29 #define STATES { \
30 CHOOSE(DISCARDING), \
31 CHOOSE(LEARNING), \
32 CHOOSE(FORWARDING), \
33 }
34
35 #define GET_STATE_NAME STP_sttrans_get_state_name
36 #include "choose.h"
37
38
39 #ifdef STRONGLY_SPEC_802_1W
40 static Bool
41 disableLearning (STATE_MACH_T *this)
42 {
43 register PORT_T *port = this->owner.port;
44
45 return STP_OUT_set_learning (port->port_index, port->owner->vlan_id, False);
46 }
47
48 static Bool
49 enableLearning (STATE_MACH_T *this)
50 {
51 register PORT_T *port = this->owner.port;
52
53 return STP_OUT_set_learning (port->port_index, port->owner->vlan_id, True);
54 }
55
56 static Bool
57 disableForwarding (STATE_MACH_T *this)
58 {
59 register PORT_T *port = this->owner.port;
60
61 return STP_OUT_set_forwarding (port->port_index, port->owner->vlan_id, False);
62 }
63
64 static Bool
65 enableForwarding (STATE_MACH_T *this)
66 {
67 register PORT_T *port = this->owner.port;
68
69 return STP_OUT_set_forwarding (port->port_index, port->owner->vlan_id, True);
70 }
71 #endif
72
73 void
74 STP_sttrans_enter_state (STATE_MACH_T *this)
75 {
76 register PORT_T *port = this->owner.port;
77
78 switch (this->State) {
79 case BEGIN:
80 case DISCARDING:
81 port->learning = False;
82 port->forwarding = False;
83 #ifdef STRONGLY_SPEC_802_1W
84 disableLearning (this);
85 disableForwarding (this);
86 #else
87 STP_OUT_set_port_state (port->port_index, port->owner->vlan_id, UID_PORT_DISCARDING);
88 #endif
89 break;
90 case LEARNING:
91 port->learning = True;
92 #ifdef STRONGLY_SPEC_802_1W
93 enableLearning (this);
94 #else
95 STP_OUT_set_port_state (port->port_index, port->owner->vlan_id, UID_PORT_LEARNING);
96 #endif
97 break;
98 case FORWARDING:
99 port->tc = !port->operEdge;
100 port->forwarding = True;
101 #ifdef STRONGLY_SPEC_802_1W
102 enableForwarding (this);
103 #else
104 STP_OUT_set_port_state (port->port_index, port->owner->vlan_id, UID_PORT_FORWARDING);
105 #endif
106 break;
107 }
108
109 }
110
111 Bool
112 STP_sttrans_check_conditions (STATE_MACH_T *this)
113 {
114 register PORT_T *port = this->owner.port;
115
116 if (BEGIN == this->State) {
117 return STP_hop_2_state (this, DISCARDING);
118 }
119
120 switch (this->State) {
121 case DISCARDING:
122 if (port->learn) {
123 return STP_hop_2_state (this, LEARNING);
124 }
125 break;
126 case LEARNING:
127 if (port->forward) {
128 return STP_hop_2_state (this, FORWARDING);
129 }
130 if (!port->learn) {
131 return STP_hop_2_state (this, DISCARDING);
132 }
133 break;
134 case FORWARDING:
135 if (!port->forward) {
136 return STP_hop_2_state (this, DISCARDING);
137 }
138 break;
139 }
140
141 return False;
142 }
143