stp_conditions.c
Go to the documentation of this file.
1 /**
2  * @file stp_conditions.c
3  * @brief STP algorithm conditions
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.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL STP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "stp/stp.h"
36 #include "stp/stp_conditions.h"
37 #include "stp/stp_misc.h"
38 #include "debug.h"
39 
40 //Check TCP/IP stack configuration
41 #if (STP_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Test whether the bridge is the Root bridge
46  * @param[in] context Pointer to the STP bridge context
47  * @return TRUE if the bridge has been selected as the Root, else FALSE
48  **/
49 
51 {
52  bool_t res;
53 
54  //Check if the Designated Root and Bridge Identifier parameters held for
55  //the bridge are the same
56  if(stpCompareBridgeId(&context->designatedRoot, &context->bridgeId) == 0)
57  {
58  res = TRUE;
59  }
60  else
61  {
62  res = FALSE;
63  }
64 
65  //Return TRUE if the bridge has been selected as the Root
66  return res;
67 }
68 
69 
70 /**
71  * @brief Test whether the bridge is the Designated bridge for at least one LAN
72  * @param[in] context Pointer to the STP bridge context
73  * @return TRUE if the bridge is the Designated bridge for at least one of the
74  * LANs, else FALSE
75  **/
76 
78 {
79  uint_t i;
80  bool_t res;
82 
83  //Initialize boolean
84  res = FALSE;
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  //Check if the bridge is the Designated bridge for the LAN to which the
93  //port is attached
94  if(stpCompareBridgeId(&port->designatedBridge, &context->bridgeId) == 0)
95  {
96  res = TRUE;
97  }
98  }
99 
100  //Return TRUE if the bridge is the Designated bridge for at least one of
101  //the LANs
102  return res;
103 }
104 
105 
106 /**
107  * @brief Test whether a given port is the Root port for the bridge
108  * @param[in] port Pointer to the bridge port context
109  * @return TRUE if the port is the Root port for the bridge, else FALSE
110  **/
111 
113 {
114  bool_t res;
115 
116  //Root port?
117  if(stpComparePortNum(port->portId, port->context->rootPort) == 0)
118  {
119  res = TRUE;
120  }
121  else
122  {
123  res = FALSE;
124  }
125 
126  //Return TRUE if the port is the Root port for the bridge
127  return res;
128 }
129 
130 
131 /**
132  * @brief Test whether a given port is a Designated port
133  * @param[in] port Pointer to the bridge port context
134  * @return TRUE if the port is the Designated port for the LAN to which it is
135  * attached, else FALSE
136  **/
137 
139 {
140  bool_t res;
141  StpBridgeContext *context;
142 
143  //Point to the STP bridge context
144  context = port->context;
145 
146  //Check whether the value of the Designated Bridge and Designated Port
147  //parameters held for the port are the same as that of the Bridge Identifier
148  //and the Port Identifier for that port, respectively
149  if(stpCompareBridgeId(&port->designatedBridge, &context->bridgeId) == 0 &&
150  port->designatedPort == port->portId)
151  {
152  res = TRUE;
153  }
154  else
155  {
156  res = FALSE;
157  }
158 
159  //Return TRUE if the port is the Designated port for the LAN to which it is
160  //attached
161  return res;
162 }
163 
164 
165 /**
166  * @brief Check whether the protocol information supersedes that already held
167  * for a port
168  * @param[in] port Pointer to the bridge port context
169  * @param[in] bpdu Pointer to the received Configuration BPDU
170  * @return TRUE if the Configuration BPDU conveys protocol information that
171  * supersedes that already held, else FALSE
172  **/
173 
175 {
176  bool_t res;
179  StpBridgeContext *context;
180 
181  //Point to the STP bridge context
182  context = port->context;
183 
184  //Extract the Root Identifier and the Bridge Identifier from the received
185  //Configuration PBDU
186  rootId.priority = ntohs(bpdu->rootId.priority);
187  rootId.addr = bpdu->rootId.addr;
188  bridgeId.priority = ntohs(bpdu->bridgeId.priority);
189  bridgeId.addr = bpdu->bridgeId.addr;
190 
191  //Initialize boolean
192  res = FALSE;
193 
194  //Check whether the Configuration BPDU conveys protocol information that
195  //supersedes that already held
196  if(stpCompareBridgeId(&rootId, &port->designatedRoot) < 0)
197  {
198  //Case 1. The Root Identifier denotes a bridge of higher priority than
199  //that recorded as the Designated Root
200  res = TRUE;
201  }
202  else if(stpCompareBridgeId(&rootId, &port->designatedRoot) > 0)
203  {
204  }
205  else if(ntohl(bpdu->rootPathCost) < port->designatedCost)
206  {
207  //Case 2. The Root Identifier is the same as the Designated Root, and
208  //the Root Path Cost is lower than that recorded as the Designated Cost
209  //for the port
210  res = TRUE;
211  }
212  else if(ntohl(bpdu->rootPathCost) > port->designatedCost)
213  {
214  }
215  else if(stpCompareBridgeId(&bridgeId, &port->designatedBridge) < 0)
216  {
217  //Case 3. The Root Identifier and Root Path Cost are as recorded for the
218  //port, and the Bridge Identifier denotes a bridge of higher priority than
219  //that recorded as the Designated Bridge for the port
220  res = TRUE;
221  }
222  else if(stpCompareBridgeId(&bridgeId, &port->designatedBridge) > 0)
223  {
224  }
225  else
226  {
227  //Case 4. The Root Identifier and Root Path Cost are as recorded for the
228  //port, and the Bridge Identifier is the same as that recorded as the
229  //Designated Bridge for the Port
230  if(stpCompareBridgeId(&bridgeId, &context->bridgeId) != 0)
231  {
232  //The Bridge receiving the BPDU is not the Designated Bridge for the
233  //port
234  res = TRUE;
235  }
236  else if(ntohs(bpdu->portId) <= port->designatedPort)
237  {
238  //The Port Identifier denotes a port of priority not less than that
239  //recorded as the Designated Port
240  res = TRUE;
241  }
242  else
243  {
244  }
245  }
246 
247  //Return boolean value
248  return res;
249 }
250 
251 #endif
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
#define ntohl(value)
Definition: cpu_endian.h:422
#define ntohs(value)
Definition: cpu_endian.h:421
Debugging facilities.
uint16_t port
Definition: dns_common.h:267
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
const uint8_t res[]
StpBridgeId rootId
Definition: rstp_bpdu.h:102
StpBridgeId bridgeId
Definition: rstp_bpdu.h:104
STP (Spanning Tree Protocol)
#define StpBridgeContext
Definition: stp.h:36
#define StpBridgePort
Definition: stp.h:40
StpBpdu
Definition: stp_bpdu.h:99
StpBridgeId
Definition: stp_common.h:148
bool_t stpSupersedesPortInfo(StpBridgePort *port, const StpBpdu *bpdu)
Check whether the protocol information supersedes that already held for a port.
bool_t stpRootPort(StpBridgePort *port)
Test whether a given port is the Root port for the bridge.
bool_t stpDesignatedBridge(StpBridgeContext *context)
Test whether the bridge is the Designated bridge for at least one LAN.
bool_t stpDesignatedPort(StpBridgePort *port)
Test whether a given port is a Designated port.
bool_t stpRootBridge(StpBridgeContext *context)
Test whether the bridge is the Root bridge.
STP algorithm conditions.
int_t stpComparePortNum(uint16_t portId1, uint16_t portId2)
Compare port numbers.
Definition: stp_misc.c:244
int_t stpCompareBridgeId(const StpBridgeId *id1, const StpBridgeId *id2)
Compare bridge identifiers.
Definition: stp_misc.c:296
STP helper functions.