rstp_fsm.c
Go to the documentation of this file.
1 /**
2  * @file rstp_fsm.c
3  * @brief Rapid Spanning Tree state machines
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSTP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL RSTP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "rstp/rstp.h"
36 #include "rstp/rstp_fsm.h"
37 #include "rstp/rstp_misc.h"
38 #include "debug.h"
39 
40 //Check TCP/IP stack configuration
41 #if (RSTP_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief RSTP state machine initialization
46  * @param[in] context Pointer to the RSTP bridge context
47  **/
48 
50 {
51  uint_t i;
53 
54  //The first (RootBridgeID) and third (DesignatedBridgeID) components of
55  //the bridge priority vector are both equal to the value of the Bridge
56  //Identifier. The other components are zero
57  context->bridgePriority.rootBridgeId = context->bridgeId;
58  context->bridgePriority.rootPathCost = 0;
59  context->bridgePriority.designatedBridgeId = context->bridgeId;
60  context->bridgePriority.designatedPortId = 0;
61  context->bridgePriority.bridgePortId = 0;
62 
63  //BridgeTimes comprises four components (the current values of Bridge Forward
64  //Delay, Bridge Hello Time, and Bridge Max Age, and a Message Age of zero)
65  context->bridgeTimes.forwardDelay = context->params.bridgeForwardDelay;
66  context->bridgeTimes.helloTime = context->params.bridgeHelloTime;
67  context->bridgeTimes.maxAge = context->params.bridgeMaxAge;
68  context->bridgeTimes.messageAge = 0;
69 
70  //Initialize bridge's root priority vector
71  context->rootPriority = context->bridgePriority;
72  //Initialize bridge's rootTimes parameter
73  context->rootTimes = context->bridgeTimes;
74 
75  //The value of the ageingTime parameter is normally Ageing Time
76  context->ageingTime = context->params.ageingTime;
77  //Reset rapid ageing timer
78  context->rapidAgeingWhile = 0;
79 
80  //Restore default ageing time
81  rstpUpdateAgeingTime(context, context->params.ageingTime);
82 
83  //Clear BPDU
84  osMemset(&context->bpdu, 0, sizeof(RstpBpdu));
85 
86  //Loop through the ports of the bridge
87  for(i = 0; i < context->numPorts; i++)
88  {
89  //Point to the current bridge port
90  port = &context->ports[i];
91 
92  //The designatedTimes for each port is set equal to the value of rootTimes
93  //except for the Hello Time component, which is set equal to BridgeTimes'
94  //Hello Time
95  port->designatedTimes = context->rootTimes;
96  port->designatedTimes.helloTime = context->bridgeTimes.helloTime;
97 
98  //Initialize msgPriority and msgTimes for each port
99  memset(&port->msgPriority, 0, sizeof(RstpPriority));
100  memset(&port->msgTimes, 0, sizeof(RstpTimes));
101 
102  //Reset parameters
103  port->disputed = FALSE;
104  port->rcvdInfo = RSTP_RCVD_INFO_OTHER;
105  port->rcvdTc = FALSE;
106  port->rcvdTcAck = FALSE;
107  port->rcvdTcn = FALSE;
108  port->tcProp = FALSE;
109  port->updtInfo = FALSE;
110  }
111 
112  //One instance of the Port Role Selection state machine is implemented for
113  //the bridge
114  rstpPrsInit(context);
115 
116  //One instance of each of the other state machines is implemented per port
117  for(i = 0; i < context->numPorts; i++)
118  {
119  //Point to the current bridge port
120  port = &context->ports[i];
121 
122  //Initialize Port Timers state machine
123  rstpPtiInit(port);
124  //Initialize Port Receive state machine
125  rstpPrxInit(port);
126  //Initialize Port Protocol Migration state machine
127  rstpPpmInit(port);
128  //Initialize Bridge Detection state machine
129  rstpBdmInit(port);
130  //Initialize Port Transmit state machine
131  rstpPtxInit(port);
132  //Initialize Port Information state machine
133  rstpPimInit(port);
134  //Initialize Port Role Transition state machine
135  rstpPrtInit(port);
136  //Initialize Port State Transition state machine
137  rstpPstInit(port);
138  //Initialize Topology Change state machine
139  rstpTcmInit(port);
140  }
141 
142  //Update RSTP state machine
143  rstpFsm(context);
144 }
145 
146 
147 /**
148  * @brief RSTP state machine implementation
149  * @param[in] context Pointer to the RSTP bridge context
150  **/
151 
153 {
154  uint_t i;
156 
157  //The behavior of an RSTP implementation in a bridge is specified by a
158  //number of cooperating state machines
159  do
160  {
161  //Clear the busy flag
162  context->busy = FALSE;
163 
164  //A single Port Role Selection state machine shall be implemented per
165  //bridge
166  rstpPrsFsm(context);
167 
168  //One instance of each of the other state machines shall be implemented
169  //per bridge port (refer to IEEE Std 802.1D-2004, section 17.15)
170  for(i = 0; i < context->numPorts; i++)
171  {
172  //Point to the current bridge port
173  port = &context->ports[i];
174 
175  //Port Timers state machine
176  rstpPtiFsm(port);
177  //Port Receive state machine
178  rstpPrxFsm(port);
179  //Port Protocol Migration state machine
180  rstpPpmFsm(port);
181  //Bridge Detection state machine
182  rstpBdmFsm(port);
183  //Port Information state machine
184  rstpPimFsm(port);
185  //Port Role Transition state machine
186  rstpPrtFsm(port);
187  //Port State Transition state machine
188  rstpPstFsm(port);
189  //Topology Change state machine
190  rstpTcmFsm(port);
191 
192  //The fdbFlush flag is set by the topology change state machine to
193  //instruct the filtering database to remove all entries for this port
194  if(port->fdbFlush)
195  {
196  //Flush the filtering database for the specified port
198  }
199  }
200 
201  //Check whether the RSTP state machine is idle
202  if(!context->busy)
203  {
204  //Loop through the ports of the bridge
205  for(i = 0; i < context->numPorts; i++)
206  {
207  //Point to the current bridge port
208  port = &context->ports[i];
209 
210  //Update Port Transmit state machine for each port
211  rstpPtxFsm(port);
212  }
213  }
214 
215  //Transition conditions are evaluated continuously as long as the RSTP
216  //state machine is busy
217  } while(context->busy);
218 }
219 
220 
221 /**
222  * @brief RSTP state machine error handler
223  * @param[in] context Pointer to the RSTP bridge context
224  **/
225 
227 {
228  //Debug message
229  TRACE_ERROR("RSTP state machine error!\r\n");
230 }
231 
232 #endif
void rstpPstFsm(RstpBridgePort *port)
PST state machine implementation.
Definition: rstp_pst.c:71
void rstpPstInit(RstpBridgePort *port)
PST state machine initialization.
Definition: rstp_pst.c:59
void rstpPtxInit(RstpBridgePort *port)
PTX state machine initialization.
Definition: rstp_ptx.c:63
void rstpTcmFsm(RstpBridgePort *port)
TCM state machine implementation.
Definition: rstp_tcm.c:76
RSTP helper functions.
Spanning Tree priority vector.
Definition: rstp.h:280
void rstpPrsFsm(RstpBridgeContext *context)
PRS state machine implementation.
Definition: rstp_prs.c:70
RSTP timer parameter values.
Definition: rstp.h:267
#define TRACE_ERROR(...)
Definition: debug.h:75
#define RstpBridgeContext
Definition: rstp.h:36
void rstpPtiInit(RstpBridgePort *port)
PTI state machine initialization.
Definition: rstp_pti.c:57
void rstpPrxInit(RstpBridgePort *port)
PRX state machine initialization.
Definition: rstp_prx.c:59
#define FALSE
Definition: os_port.h:46
void rstpPimFsm(RstpBridgePort *port)
PIM state machine implementation.
Definition: rstp_pim.c:78
void rstpPimInit(RstpBridgePort *port)
PIM state machine initialization.
Definition: rstp_pim.c:66
void rstpTcmInit(RstpBridgePort *port)
TCM state machine initialization.
Definition: rstp_tcm.c:64
void rstpBdmFsm(RstpBridgePort *port)
BDM state machine implementation.
Definition: rstp_bdm.c:77
RSTP (Rapid Spanning Tree Protocol)
void rstpUpdateAgeingTime(RstpBridgeContext *context, uint32_t ageingTime)
Set ageing time for dynamic filtering entries.
Definition: rstp_misc.c:527
void rstpPpmFsm(RstpBridgePort *port)
PPM state machine implementation.
Definition: rstp_ppm.c:71
void rstpFsmInit(RstpBridgeContext *context)
RSTP state machine initialization.
Definition: rstp_fsm.c:49
void rstpBdmInit(RstpBridgePort *port)
BDM state machine initialization.
Definition: rstp_bdm.c:58
void rstpPpmInit(RstpBridgePort *port)
PPM state machine initialization.
Definition: rstp_ppm.c:59
RstpBpdu
Definition: rstp_bpdu.h:111
void rstpPrtFsm(RstpBridgePort *port)
PRT state machine implementation.
Definition: rstp_prt.c:91
void rstpPrtInit(RstpBridgePort *port)
PRT state machine initialization.
Definition: rstp_prt.c:79
uint16_t port
Definition: dns_common.h:267
void rstpFsmError(RstpBridgeContext *context)
RSTP state machine error handler.
Definition: rstp_fsm.c:226
void rstpPtxFsm(RstpBridgePort *port)
PTX state machine implementation.
Definition: rstp_ptx.c:75
void rstpPrxFsm(RstpBridgePort *port)
PRX state machine implementation.
Definition: rstp_prx.c:71
void rstpRemoveFdbEntries(RstpBridgePort *port)
Remove filtering database entries (immediately or by rapid ageing)
Definition: rstp_misc.c:660
void rstpPrsInit(RstpBridgeContext *context)
PRS state machine initialization.
Definition: rstp_prs.c:58
@ RSTP_RCVD_INFO_OTHER
Definition: rstp.h:233
unsigned int uint_t
Definition: compiler_port.h:50
#define osMemset(p, value, length)
Definition: os_port.h:135
void rstpPtiFsm(RstpBridgePort *port)
PTI state machine implementation.
Definition: rstp_pti.c:70
void rstpFsm(RstpBridgeContext *context)
RSTP state machine implementation.
Definition: rstp_fsm.c:152
Debugging facilities.
#define RstpBridgePort
Definition: rstp.h:40
Rapid Spanning Tree state machines.