stp_mgmt.c
Go to the documentation of this file.
1 /**
2  * @file stp_mgmt.c
3  * @brief Management of the STP bridge
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_procedures.h"
37 #include "stp/stp_conditions.h"
38 #include "stp/stp_misc.h"
39 #include "debug.h"
40 
41 //Check TCP/IP stack configuration
42 #if (STP_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief Set bridge priority
47  * @param[in] context Pointer to the STP bridge context
48  * @param[in] value Bridge priority
49  * @param[in] commit If this flag is TRUE, the bridge verifies the parameter
50  * value and commits the change if the value is valid. If FALSE, the bridge
51  * only performs the verification and does not take any further action
52  * @return Error code
53  **/
54 
56  bool_t commit)
57 {
58  uint_t i;
59  bool_t rootBridge;
60  StpBridgeId newBridgeId;
61 
62  //Make sure the STP bridge context is valid
63  if(context == NULL)
64  return ERROR_WRITE_FAILED;
65 
66  //Commit phase?
67  if(commit)
68  {
69  //Any parameter change?
70  if(value != context->bridgeId.priority)
71  {
72  //Test whether the bridge is currently the Root
73  rootBridge = stpRootBridge(context);
74 
75  //The new value of the Bridge Identifier is calculated
76  newBridgeId.addr = context->bridgeId.addr;
77  newBridgeId.priority = value;
78 
79  //The value of the Designated Bridge parameter held for each port that
80  //has been selected as the Designated port for the LAN to which it is
81  //attached is set to the new value of the Bridge Identifier
82  for(i = 0; i < context->numPorts; i++)
83  {
84  //Designated port?
85  if(stpDesignatedPort(&context->ports[i]))
86  {
87  context->ports[i].designatedBridge = newBridgeId;
88  }
89  }
90 
91  //The Bridge Identifier held by the bridge is set to the new value
92  context->bridgeId = newBridgeId;
93  //The Configuration Update procedure is used
94  stpConfigUpdate(context);
95  //The Port State Selection procedure is used
96  stpPortStateSelection(context);
97 
98  //Check if the bridge has been selected as the Root following
99  //Configuration Update
100  if(!rootBridge && stpRootBridge(context))
101  {
102  //The Max Age, Hello Time, and Forward Delay parameters held by the
103  //bridge are set to the values of the Bridge Max Age, Bridge Hello
104  //Time, and Bridge Forward Delay parameters
105  context->maxAge = context->bridgeMaxAge;
106  context->helloTime = context->bridgeHelloTime;
107  context->forwardDelay = context->bridgeForwardDelay;
108 
109  //The Topology Change Detection procedure is used
111  //The Topology Change Notification Timer is stopped
112  stpStopTimer(&context->tcnTimer);
113 
114  //The Configuration BPDU Generation procedure is invoked and the
115  //Hello Timer is started
116  stpConfigBpduGeneration(context);
117  stpStartTimer(&context->helloTimer, 0);
118  }
119  }
120  }
121 
122  //Successful processing
123  return NO_ERROR;
124 }
125 
126 
127 /**
128  * @brief Set Bridge Max Age parameter
129  * @param[in] context Pointer to the STP bridge context
130  * @param[in] value Value of the Bridge Max Age parameter, in seconds
131  * @param[in] commit If this flag is TRUE, the bridge verifies the parameter
132  * value and commits the change if the value is valid. If FALSE, the bridge
133  * only performs the verification and does not take any further action
134  * @return Error code
135  **/
136 
138  bool_t commit)
139 {
140  //Make sure the STP bridge context is valid
141  if(context == NULL)
142  return ERROR_WRITE_FAILED;
143 
144  //If the value of the Bridge Max Age is outside the specified range, then
145  //no action shall be taken
146  if(value < STP_MIN_BRIDGE_MAX_AGE || value > STP_MAX_BRIDGE_MAX_AGE)
147  return ERROR_WRONG_VALUE;
148 
149  //A bridge shall enforce the following relationships (refer to IEEE Std
150  //802.1D-1998, section 8.10.2)
151  if(!stpCheckBridgeParams(value, context->bridgeHelloTime,
152  context->bridgeForwardDelay))
153  {
155  }
156 
157  //Commit phase?
158  if(commit)
159  {
160  //Any parameter change?
161  if(value != context->bridgeMaxAge)
162  {
163  //The Bridge Max Age parameter specifies the value that all bridges use
164  //for MaxAge when this bridge is acting as the root
165  context->bridgeMaxAge = value;
166 
167  //Check if the bridge has been selected as the Root
168  if(stpRootBridge(context))
169  {
170  //The value of the Topology Change Time parameter is equal to the
171  //sum of the values of the bridge's Bridge Max Age and Bridge
172  //Forward Delay parameters
173  context->topologyChangeTime = context->bridgeMaxAge +
174  context->bridgeForwardDelay;
175 
176  //The Max Age parameter held by the bridge is set to the value of
177  //the Bridge Max Age parameter
178  context->maxAge = context->bridgeMaxAge;
179  }
180  }
181  }
182 
183  //Successful processing
184  return NO_ERROR;
185 }
186 
187 
188 /**
189  * @brief Set Bridge Hello Time parameter
190  * @param[in] context Pointer to the STP bridge context
191  * @param[in] value Value of the Bridge Hello Time parameter, in seconds
192  * @param[in] commit If this flag is TRUE, the bridge verifies the parameter
193  * value and commits the change if the value is valid. If FALSE, the bridge
194  * only performs the verification and does not take any further action
195  * @return Error code
196  **/
197 
199  bool_t commit)
200 {
201  //Make sure the STP bridge context is valid
202  if(context == NULL)
203  return ERROR_WRITE_FAILED;
204 
205  //If the value of the Bridge Hello Time is outside the specified range, then
206  //no action shall be taken
207  if(value < STP_MIN_BRIDGE_HELLO_TIME || value > STP_MAX_BRIDGE_HELLO_TIME)
208  return ERROR_WRONG_VALUE;
209 
210  //A bridge shall enforce the following relationships (refer to IEEE Std
211  //802.1D-1998, section 8.10.2)
212  if(!stpCheckBridgeParams(context->bridgeMaxAge, value,
213  context->bridgeForwardDelay))
214  {
216  }
217 
218  //Commit phase?
219  if(commit)
220  {
221  //Any parameter change?
222  if(value != context->bridgeHelloTime)
223  {
224  //The Bridge Hello Time parameter specifies the value that all bridges
225  //use for HelloTime when this bridge is acting as the root
226  context->bridgeHelloTime = value;
227 
228  //Check if the bridge has been selected as the Root
229  if(stpRootBridge(context))
230  {
231  //The Hello Time parameter held by the bridge is set to the value of
232  //the Bridge Hello Time parameter
233  context->helloTime = context->bridgeHelloTime;
234  }
235  }
236  }
237 
238  //Successful processing
239  return NO_ERROR;
240 }
241 
242 
243 /**
244  * @brief Set Bridge Forward Delay parameter
245  * @param[in] context Pointer to the STP bridge context
246  * @param[in] value Value of the Bridge Forward Delay parameter, in seconds
247  * @param[in] commit If this flag is TRUE, the bridge verifies the parameter
248  * value and commits the change if the value is valid. If FALSE, the bridge
249  * only performs the verification and does not take any further action
250  * @return Error code
251  **/
252 
254  bool_t commit)
255 {
256  //Make sure the STP bridge context is valid
257  if(context == NULL)
258  return ERROR_WRITE_FAILED;
259 
260  //If the value of the Bridge Forward Delay is outside the specified range,
261  //then no action shall be taken
262  if(value < STP_MIN_BRIDGE_FORWARD_DELAY || value > STP_MAX_BRIDGE_FORWARD_DELAY)
263  return ERROR_WRONG_VALUE;
264 
265  //A bridge shall enforce the following relationships (refer to IEEE Std
266  //802.1D-1998, section 8.10.2)
267  if(!stpCheckBridgeParams(context->bridgeMaxAge, context->bridgeHelloTime,
268  value))
269  {
271  }
272 
273  //Commit phase?
274  if(commit)
275  {
276  //Any parameter change?
277  if(value != context->bridgeForwardDelay)
278  {
279  //The Bridge Forward Delay parameter specifies the value that all
280  //bridges use for ForwardDelay when this bridge is acting as the root
281  context->bridgeForwardDelay = value;
282 
283  //Check if the bridge has been selected as the Root
284  if(stpRootBridge(context))
285  {
286  //The value of the Topology Change Time parameter is equal to the
287  //sum of the values of the bridge's Bridge Max Age and Bridge
288  //Forward Delay parameters
289  context->topologyChangeTime = context->bridgeMaxAge +
290  context->bridgeForwardDelay;
291 
292  //The Forward Delay parameter held by the bridge is set to the
293  //value of the Bridge Forward Delay parameter
294  context->forwardDelay = context->bridgeForwardDelay;
295  }
296  }
297  }
298 
299  //Successful processing
300  return NO_ERROR;
301 }
302 
303 
304 /**
305  * @brief Set Ageing Time parameter
306  * @param[in] context Pointer to the STP bridge context
307  * @param[in] value Value of the Ageing Time parameter
308  * @param[in] commit If this flag is TRUE, the bridge verifies the parameter
309  * value and commits the change if the value is valid. If FALSE, the bridge
310  * only performs the verification and does not take any further action
311  * @return Error code
312  **/
313 
315  bool_t commit)
316 {
317  //Make sure the STP bridge context is valid
318  if(context == NULL)
319  return ERROR_WRITE_FAILED;
320 
321  //If the value of the Ageing Time is outside the specified range, then no
322  //action shall be taken
323  if(value < STP_MIN_AGEING_TIME || value > STP_MAX_AGEING_TIME)
324  return ERROR_WRONG_VALUE;
325 
326  //Commit phase?
327  if(commit)
328  {
329  //Any parameter change?
330  if(value != context->ageingTime)
331  {
332  //The Ageing Time parameter is updated using the supplied value
333  context->ageingTime = value;
334 
335  //Check whether the rapid ageing timer is stopped
336  if(!context->rapidAgeingTimer.active)
337  {
338  //Set the ageing time for dynamic filtering entries
339  stpUpdateAgeingTime(context, context->ageingTime);
340  }
341  }
342  }
343 
344  //Successful processing
345  return NO_ERROR;
346 }
347 
348 
349 /**
350  * @brief Get the number of ports
351  * @param[in] context Pointer to the STP bridge context
352  * @param[out] value Number of ports
353  * @return Error code
354  **/
355 
357 {
358  //Check parameters
359  if(context == NULL || value == NULL)
360  return ERROR_READ_FAILED;
361 
362  //Retrieve the number of ports
363  *value = context->numPorts;
364 
365  //Successful processing
366  return NO_ERROR;
367 }
368 
369 /**
370  * @brief Get the MAC address assigned to the bridge
371  * @param[in] context Pointer to the STP bridge context
372  * @param[out] value MAC address of the bridge
373  * @return Error code
374  **/
375 
377 {
378  //Check parameters
379  if(context == NULL || value == NULL)
380  return ERROR_READ_FAILED;
381 
382  //Retrieve the bridge identifier
383  *value = context->bridgeId.addr;
384 
385  //Successful processing
386  return NO_ERROR;
387 }
388 
389 
390 /**
391  * @brief Get the assigned bridge priority
392  * @param[in] context Pointer to the STP bridge context
393  * @param[out] value Bridge priority
394  * @return Error code
395  **/
396 
398 {
399  //Check parameters
400  if(context == NULL || value == NULL)
401  return ERROR_READ_FAILED;
402 
403  //Retrieve the bridge priority
404  *value = context->bridgeId.priority;
405 
406  //Successful processing
407  return NO_ERROR;
408 }
409 
410 
411 /**
412  * @brief Get the assigned value of the Bridge Max Age parameter
413  * @param[in] context Pointer to the STP bridge context
414  * @param[out] value Value of the Bridge Max Age parameter, in seconds
415  * @return Error code
416  **/
417 
419 {
420  //Check parameters
421  if(context == NULL || value == NULL)
422  return ERROR_READ_FAILED;
423 
424  //Retrieve the value of the Bridge Max Age parameter
425  *value = context->bridgeMaxAge;
426 
427  //Successful processing
428  return NO_ERROR;
429 }
430 
431 
432 /**
433  * @brief Get the assigned value of the Bridge Hello Time parameter
434  * @param[in] context Pointer to the STP bridge context
435  * @param[out] value Value of the Bridge Hello Time parameter, in seconds
436  * @return Error code
437  **/
438 
440 {
441  //Check parameters
442  if(context == NULL || value == NULL)
443  return ERROR_READ_FAILED;
444 
445  //Retrieve the value of the Bridge Hello Time parameter
446  *value = context->bridgeHelloTime;
447 
448  //Successful processing
449  return NO_ERROR;
450 }
451 
452 
453 /**
454  * @brief Get the assigned value of the Bridge Forward Delay parameter
455  * @param[in] context Pointer to the STP bridge context
456  * @param[out] value Value of the Bridge Forward Delay parameter, in seconds
457  * @return Error code
458  **/
459 
461 {
462  //Check parameters
463  if(context == NULL || value == NULL)
464  return ERROR_READ_FAILED;
465 
466  //Retrieve the value of the Bridge Forward Delay parameter
467  *value = context->bridgeForwardDelay;
468 
469  //Successful processing
470  return NO_ERROR;
471 }
472 
473 
474 /**
475  * @brief Get the assigned value of the Hold Time parameter
476  * @param[in] context Pointer to the STP bridge context
477  * @param[out] value Value of the Transmit Hold Count parameter
478  * @return Error code
479  **/
480 
482 {
483  //Check parameters
484  if(context == NULL || value == NULL)
485  return ERROR_READ_FAILED;
486 
487  //Retrieve the value of the Hold Time parameter
488  *value = context->holdTime;
489 
490  //Successful processing
491  return NO_ERROR;
492 }
493 
494 
495 /**
496  * @brief Get the assigned value of the Ageing Time parameter
497  * @param[in] context Pointer to the STP bridge context
498  * @param[out] value Value of the Ageing Time parameter
499  * @return Error code
500  **/
501 
503 {
504  //Check parameters
505  if(context == NULL || value == NULL)
506  return ERROR_READ_FAILED;
507 
508  //Retrieve the value of the Ageing Time parameter
509  *value = context->ageingTime;
510 
511  //Successful processing
512  return NO_ERROR;
513 }
514 
515 
516 /**
517  * @brief Get the bridge identifier of the root of the spanning tree
518  * @param[in] context Pointer to the STP bridge context
519  * @param[out] value Bridge identifier
520  * @return Error code
521  **/
522 
524 {
525  //Check parameters
526  if(context == NULL || value == NULL)
527  return ERROR_READ_FAILED;
528 
529  //Retrieve the bridge identifier of the root of the spanning tree, as
530  //determined by the Spanning Tree Protocol
531  *value = context->designatedRoot;
532 
533  //Successful processing
534  return NO_ERROR;
535 }
536 
537 
538 /**
539  * @brief Get the current cost of the path to the root
540  * @param[in] context Pointer to the STP bridge context
541  * @param[out] value Root path cost
542  * @return Error code
543  **/
544 
546 {
547  //Check parameters
548  if(context == NULL || value == NULL)
549  return ERROR_READ_FAILED;
550 
551  //Retrieve the cost of the path to the root as seen from this bridge
552  *value = context->rootPathCost;
553 
554  //Successful processing
555  return NO_ERROR;
556 }
557 
558 
559 /**
560  * @brief Get the current root port
561  * @param[in] context Pointer to the STP bridge context
562  * @param[out] value Port number
563  * @return Error code
564  **/
565 
567 {
568  //Check parameters
569  if(context == NULL || value == NULL)
570  return ERROR_READ_FAILED;
571 
572  //Retrieve the port through which the path to the Root is established. This
573  //value not significant when the bridge is the Root, and is set to zero
574  *value = context->rootPort & STP_PORT_NUM_MASK;
575 
576  //Successful processing
577  return NO_ERROR;
578 }
579 
580 
581 /**
582  * @brief Get the current Max Age value
583  * @param[in] context Pointer to the STP bridge context
584  * @param[out] value Max Age value, in seconds
585  * @return Error code
586  **/
587 
589 {
590  //Check parameters
591  if(context == NULL || value == NULL)
592  return ERROR_READ_FAILED;
593 
594  //Retrieve the maximum age of Spanning Tree Protocol information learned
595  //from the network on any port before it is discarded
596  *value = context->maxAge;
597 
598  //Successful processing
599  return NO_ERROR;
600 }
601 
602 
603 /**
604  * @brief Get the current Hello Time value
605  * @param[in] context Pointer to the STP bridge context
606  * @param[out] value Hello Time value, in seconds
607  * @return Error code
608  **/
609 
611 {
612  //Check parameters
613  if(context == NULL || value == NULL)
614  return ERROR_READ_FAILED;
615 
616  //Retrieve the amount of time between the transmission of Configuration
617  //bridge PDUs by this node on any port when it is the root of the spanning
618  //tree, or trying to become so
619  *value = context->helloTime;
620 
621  //Successful processing
622  return NO_ERROR;
623 }
624 
625 
626 /**
627  * @brief Get the current Forward Delay value
628  * @param[in] context Pointer to the STP bridge context
629  * @param[out] value Forward Delay value, in seconds
630  * @return Error code
631  **/
632 
634 {
635  //Check parameters
636  if(context == NULL || value == NULL)
637  return ERROR_READ_FAILED;
638 
639  //The Forward Delay value determines how long the port stays in each of the
640  //Listening and Learning states, which precede the Forwarding state
641  *value = context->forwardDelay;
642 
643  //Successful processing
644  return NO_ERROR;
645 }
646 
647 
648 /**
649  * @brief Get the number of topology changes
650  * @param[in] context Pointer to the STP bridge context
651  * @param[out] value Number of topology changes
652  * @return Error code
653  **/
654 
656 {
657  //Check parameters
658  if(context == NULL || value == NULL)
659  return ERROR_READ_FAILED;
660 
661  //Retrieve the number of topology changes
662  *value = context->topologyChangeCount;
663 
664  //Successful processing
665  return NO_ERROR;
666 }
667 
668 
669 /**
670  * @brief Get the time since a topology change was last detected
671  * @param[in] context Pointer to the STP bridge context
672  * @param[out] value Time since a topology change was last detected
673  * @return Error code
674  **/
675 
677  uint_t *value)
678 {
679  //Check parameters
680  if(context == NULL || value == NULL)
681  return ERROR_READ_FAILED;
682 
683  //Retrieve the time since a topology change was last detected by the bridge
684  *value = context->timeSinceTopologyChange;
685 
686  //Successful processing
687  return NO_ERROR;
688 }
689 
690 
691 /**
692  * @brief Set port priority
693  * @param[in] context Pointer to the STP bridge context
694  * @param[in] portIndex Port index
695  * @param[in] value Port priority
696  * @param[in] commit If this flag is TRUE, the bridge verifies the parameter
697  * value and commits the change if the value is valid. If FALSE, the bridge
698  * only performs the verification and does not take any further action
699  * @return Error code
700  **/
701 
703  uint8_t value, bool_t commit)
704 {
705  uint16_t newPortId;
707 
708  //Make sure the STP bridge context is valid
709  if(context == NULL)
710  return ERROR_WRITE_FAILED;
711 
712  //Invalid port index?
713  if(portIndex < 1 || portIndex > context->numPorts)
714  return ERROR_INVALID_PORT;
715 
716  //Point to the port that matches the specified port index
717  port = &context->ports[portIndex - 1];
718 
719  //Commit phase?
720  if(commit)
721  {
722  //Any parameter change?
723  if(value != ((port->portId & STP_PORT_PRIORITY_MASK) >> 8))
724  {
725  //The new value of the Port Identifier is calculated
726  newPortId = (port->portId & STP_PORT_NUM_MASK) | (value << 8);
727 
728  //Check if the Port has been selected as the Designated Port for the LAN
729  //to which it is attached
731  {
732  //The Designated Port parameter held for the port is set to the new
733  //value of the Port Identifier
734  port->designatedPort = newPortId;
735  }
736 
737  //The Port Identifier parameter held for the port is set to the new value
738  port->portId = newPortId;
739 
740  //Check if the value of the Designated Bridge parameter held for the
741  //port is equal to that of the bridge's Bridge Identifier, and the new
742  //value of the Port Identifier is of higher priority than that recorded
743  //as the Designated Port
744  if(stpCompareBridgeId(&port->designatedBridge, &context->bridgeId) == 0 &&
745  port->portId < port->designatedPort)
746  {
747  //The Become Designated Port procedure is used to assign values to
748  //the Designated Root, Designated Cost, Designated Bridge, and
749  //Designated Port parameters for the port
751 
752  //The Port State Selection procedure is used
753  stpPortStateSelection(context);
754  }
755  }
756  }
757 
758  //Successful processing
759  return NO_ERROR;
760 }
761 
762 
763 /**
764  * @brief Set administrative bridge port state
765  * @param[in] context Pointer to the STP bridge context
766  * @param[in] portIndex Port index
767  * @param[in] value Administrative bridge port state
768  * @param[in] commit If this flag is TRUE, the bridge verifies the parameter
769  * value and commits the change if the value is valid. If FALSE, the bridge
770  * only performs the verification and does not take any further action
771  * @return Error code
772  **/
773 
775  bool_t value, bool_t commit)
776 {
777  bool_t rootBridge;
779 
780  //Make sure the STP bridge context is valid
781  if(context == NULL)
782  return ERROR_WRITE_FAILED;
783 
784  //Invalid port index?
785  if(portIndex < 1 || portIndex > context->numPorts)
786  return ERROR_INVALID_PORT;
787 
788  //Point to the port that matches the specified port index
789  port = &context->ports[portIndex - 1];
790 
791  //Commit phase?
792  if(commit)
793  {
794  //Any parameter change?
795  if(value && port->state == STP_PORT_STATE_DISABLED)
796  {
797  //The Become Designated Port procedure is used to assign values to the
798  //Designated Root, Designated Cost, Designated Bridge, and Designated
799  //Port parameters for the port
801 
802  //The Port State is set to Blocking
804  //The Topology Change Acknowledge flag parameter is reset
805  port->topologyChangeAck = FALSE;
806  //The Configuration Pending flag parameter is reset
807  port->configPending = FALSE;
808  //The Message Age Timer is stopped, if running
809  stpStopTimer(&port->messageAgeTimer);
810  //The Forward Delay Timer is stopped, if running
811  stpStopTimer(&port->forwardDelayTimer);
812  //The Hold Timer is stopped, if running
813  stpStopTimer(&port->holdTimer);
814  //The Port State Selection procedure is used
815  stpPortStateSelection(context);
816  }
817  else if(!value && port->state != STP_PORT_STATE_DISABLED)
818  {
819  //Test whether the bridge is currently the Root
820  rootBridge = stpRootBridge(context);
821 
822  //The Become Designated Port procedure is used to assign values to the
823  //Designated Root, Designated Cost, Designated Bridge, and Designated
824  //Port parameters for the port
826 
827  //The Port State is set to Disabled
829  //The Topology Change Acknowledge flag parameter is reset
830  port->topologyChangeAck = FALSE;
831  //The Configuration Pending flag parameter is reset
832  port->configPending = FALSE;
833  //The Message Age Timer is stopped, if running
834  stpStopTimer(&port->messageAgeTimer);
835  //The Forward Delay Timer is stopped, if running
836  stpStopTimer(&port->forwardDelayTimer);
837  //The Configuration Update procedure is used
838  stpConfigUpdate(context);
839  //The Port State Selection procedure is used
840  stpPortStateSelection(context);
841 
842  //Check if the Bridge has been selected as the Root following
843  //Configuration Update
844  if(!rootBridge && stpRootBridge(context))
845  {
846  //The Max Age, Hello Time, and Forward Delay parameters held by the
847  //bridge are set to the values of the Bridge Max Age, Bridge Hello
848  //Time, and Bridge Forward Delay parameters
849  context->maxAge = context->bridgeMaxAge;
850  context->helloTime = context->bridgeHelloTime;
851  context->forwardDelay = context->bridgeForwardDelay;
852 
853  //The Topology Change Detection procedure is used
855  //The Topology Change Notification Timer is stopped
856  stpStopTimer(&context->tcnTimer);
857 
858  //The Configuration BPDU Generation procedure is invoked and the
859  //Hello Timer is started
860  stpConfigBpduGeneration(context);
861  stpStartTimer(&context->helloTimer, 0);
862  }
863  }
864  else
865  {
866  //The bridge does not take action
867  }
868  }
869 
870  //Successful processing
871  return NO_ERROR;
872 }
873 
874 
875 /**
876  * @brief Set administrative port path cost
877  * @param[in] context Pointer to the STP bridge context
878  * @param[in] portIndex Port index
879  * @param[in] value Administrative port path cost
880  * @param[in] commit If this flag is TRUE, the bridge verifies the parameter
881  * value and commits the change if the value is valid. If FALSE, the bridge
882  * only performs the verification and does not take any further action
883  * @return Error code
884  **/
885 
887  uint32_t value, bool_t commit)
888 {
890 
891  //Make sure the STP bridge context is valid
892  if(context == NULL)
893  return ERROR_WRITE_FAILED;
894 
895  //Invalid port index?
896  if(portIndex < 1 || portIndex > context->numPorts)
897  return ERROR_INVALID_PORT;
898 
899  //Check the value of the parameter
901  return ERROR_WRONG_VALUE;
902 
903  //Point to the port that matches the specified port index
904  port = &context->ports[portIndex - 1];
905 
906  //Commit phase?
907  if(commit)
908  {
909  //Any parameter change?
910  if(value != port->pathCost)
911  {
912  //The Path Cost parameter for the port is set to the new value
913  port->pathCost = value;
914 
915  //The Configuration Update procedure is used
916  stpConfigUpdate(context);
917  //The Port State Selection procedure is used
918  stpPortStateSelection(context);
919  }
920  }
921 
922  //Successful processing
923  return NO_ERROR;
924 }
925 
926 
927 /**
928  * @brief Get the MAC address assigned to the port
929  * @param[in] context Pointer to the STP bridge context
930  * @param[in] portIndex Port index
931  * @param[out] value MAC address of the individual MAC entity for the port
932  * @return Error code
933  **/
934 
936  MacAddr *value)
937 {
939 
940  //Check parameters
941  if(context == NULL || value == NULL)
942  return ERROR_READ_FAILED;
943 
944  //Invalid port index?
945  if(portIndex < 1 || portIndex > context->numPorts)
946  return ERROR_INVALID_PORT;
947 
948  //Point to the port that matches the specified port index
949  port = &context->ports[portIndex - 1];
950 
951  //Retrieve the MAC address of the individual MAC entity for the port
952  *value = port->macAddr;
953 
954  //Successful processing
955  return NO_ERROR;
956 }
957 
958 
959 /**
960  * @brief Get the priority assigned to the port
961  * @param[in] context Pointer to the STP bridge context
962  * @param[in] portIndex Port index
963  * @param[out] value Port priority
964  * @return Error code
965  **/
966 
968  uint8_t *value)
969 {
971 
972  //Check parameters
973  if(context == NULL || value == NULL)
974  return ERROR_READ_FAILED;
975 
976  //Invalid port index?
977  if(portIndex < 1 || portIndex > context->numPorts)
978  return ERROR_INVALID_PORT;
979 
980  //Point to the port that matches the specified port index
981  port = &context->ports[portIndex - 1];
982 
983  //Retrieve the priority assigned to the port
984  *value = (port->portId & STP_PORT_PRIORITY_MASK) >> 8;
985 
986  //Successful processing
987  return NO_ERROR;
988 }
989 
990 
991 /**
992  * @brief Get the administrative port state
993  * @param[in] context Pointer to the STP bridge context
994  * @param[in] portIndex Port index
995  * @param[out] value Administrative port state
996  * @return Error code
997  **/
998 
1000  bool_t *value)
1001 {
1003 
1004  //Check parameters
1005  if(context == NULL || value == NULL)
1006  return ERROR_READ_FAILED;
1007 
1008  //Invalid port index?
1009  if(portIndex < 1 || portIndex > context->numPorts)
1010  return ERROR_INVALID_PORT;
1011 
1012  //Point to the port that matches the specified port index
1013  port = &context->ports[portIndex - 1];
1014 
1015  //Retrieve the administrative port state
1016  *value = (port->state != STP_PORT_STATE_DISABLED) ? TRUE : FALSE;
1017 
1018  //Successful processing
1019  return NO_ERROR;
1020 }
1021 
1022 
1023 /**
1024  * @brief Get the current MAC operational state
1025  * @param[in] context Pointer to the STP bridge context
1026  * @param[in] portIndex Port index
1027  * @param[out] value MAC operational state
1028  * @return Error code
1029  **/
1030 
1032  bool_t *value)
1033 {
1035 
1036  //Check parameters
1037  if(context == NULL || value == NULL)
1038  return ERROR_READ_FAILED;
1039 
1040  //Invalid port index?
1041  if(portIndex < 1 || portIndex > context->numPorts)
1042  return ERROR_INVALID_PORT;
1043 
1044  //Point to the port that matches the specified port index
1045  port = &context->ports[portIndex - 1];
1046 
1047  //Retrieve the operational state of the MAC entity
1048  *value = port->macOperState;
1049 
1050  //Successful processing
1051  return NO_ERROR;
1052 }
1053 
1054 
1055 /**
1056  * @brief Get the current value of the port path cost
1057  * @param[in] context Pointer to the STP bridge context
1058  * @param[in] portIndex Port index
1059  * @param[out] value Port path cost
1060  * @return Error code
1061  **/
1062 
1064  uint32_t *value)
1065 {
1067 
1068  //Check parameters
1069  if(context == NULL || value == NULL)
1070  return ERROR_READ_FAILED;
1071 
1072  //Invalid port index?
1073  if(portIndex < 1 || portIndex > context->numPorts)
1074  return ERROR_INVALID_PORT;
1075 
1076  //Point to the port that matches the specified port index
1077  port = &context->ports[portIndex - 1];
1078 
1079  //Retrieve the contribution of this port to the path cost of paths towards
1080  //the spanning tree root which include this port
1081  *value = port->pathCost;
1082 
1083  //Successful processing
1084  return NO_ERROR;
1085 }
1086 
1087 
1088 /**
1089  * @brief Get the current state of the port
1090  * @param[in] context Pointer to the STP bridge context
1091  * @param[in] portIndex Port index
1092  * @param[out] value Port state
1093  * @return Error code
1094  **/
1095 
1098 {
1100 
1101  //Check parameters
1102  if(context == NULL || value == NULL)
1103  return ERROR_READ_FAILED;
1104 
1105  //Invalid port index?
1106  if(portIndex < 1 || portIndex > context->numPorts)
1107  return ERROR_INVALID_PORT;
1108 
1109  //Point to the port that matches the specified port index
1110  port = &context->ports[portIndex - 1];
1111 
1112  //Retrieve the port's current state, as defined by application of the
1113  //Spanning Tree Protocol
1114  if(port->state == STP_PORT_STATE_DISABLED)
1115  {
1116  //Disabled represents exclusion of the port from the active topology by
1117  //management setting of the Administrative Port State to disabled
1119  }
1120  else if(!port->macOperState)
1121  {
1122  //The broken state represents the failure or unavailability of the port's
1123  //MAC as indicated by MAC_Operational FALSE
1125  }
1126  else if(port->state == STP_PORT_STATE_BLOCKING)
1127  {
1128  //Blocking represents exclusion of the port from the active topology by
1129  //the spanning tree algorithm
1131  }
1132  else if(port->state == STP_PORT_STATE_LISTENING)
1133  {
1134  //Listening represents a port that the spanning tree algorithm has
1135  //selected to be part of the active topology (computing a Root or
1136  //Designated port role) but is temporarily discarding frames to guard
1137  //against loops or incorrect learning
1139  }
1140  else if(port->state == STP_PORT_STATE_LEARNING)
1141  {
1142  //Any port that has learning enabled but forwarding disabled has the
1143  //port state Learning
1145  }
1146  else if(port->state == STP_PORT_STATE_FORWARDING)
1147  {
1148  //A port that both learns and forwards frames has the port state
1149  //Forwarding
1151  }
1152  else
1153  {
1154  //Just for sanity
1156  }
1157 
1158  //Successful processing
1159  return NO_ERROR;
1160 }
1161 
1162 
1163 /**
1164  * @brief Get the assigned role of the port
1165  * @param[in] context Pointer to the STP bridge context
1166  * @param[in] portIndex Port index
1167  * @param[out] value Port role
1168  * @return Error code
1169  **/
1170 
1172  StpPortRole *value)
1173 {
1175 
1176  //Check parameters
1177  if(context == NULL || value == NULL)
1178  return ERROR_READ_FAILED;
1179 
1180  //Invalid port index?
1181  if(portIndex < 1 || portIndex > context->numPorts)
1182  return ERROR_INVALID_PORT;
1183 
1184  //Point to the port that matches the specified port index
1185  port = &context->ports[portIndex - 1];
1186 
1187  //Retrieve the assigned port role
1188  if(port->state == STP_PORT_STATE_DISABLED)
1189  {
1190  //The port is disabled
1192  }
1193  else if(stpRootPort(port))
1194  {
1195  //The port acts as Root port
1197  }
1198  else if(stpDesignatedPort(port))
1199  {
1200  //The port acts as Designated port
1202  }
1203  else
1204  {
1205  //An alternate port acts as a backup port in a redundantly connected
1206  //bridged LAN
1208  }
1209 
1210  //Successful processing
1211  return NO_ERROR;
1212 }
1213 
1214 
1215 /**
1216  * @brief Get the bridge identifier of the designated root bridge
1217  * @param[in] context Pointer to the STP bridge context
1218  * @param[in] portIndex Port index
1219  * @param[out] value Bridge identifier
1220  * @return Error code
1221  **/
1222 
1224  uint_t portIndex, StpBridgeId *value)
1225 {
1227 
1228  //Check parameters
1229  if(context == NULL || value == NULL)
1230  return ERROR_READ_FAILED;
1231 
1232  //Invalid port index?
1233  if(portIndex < 1 || portIndex > context->numPorts)
1234  return ERROR_INVALID_PORT;
1235 
1236  //Point to the port that matches the specified port index
1237  port = &context->ports[portIndex - 1];
1238 
1239  //Retrieve the unique Bridge Identifier of the bridge recorded as the Root
1240  //in the Configuration BPDUs transmitted by the Designated Bridge for the
1241  //segment to which the port is attached
1242  *value = port->designatedRoot;
1243 
1244  //Successful processing
1245  return NO_ERROR;
1246 }
1247 
1248 
1249 /**
1250  * @brief Get the designated cost of the port
1251  * @param[in] context Pointer to the STP bridge context
1252  * @param[in] portIndex Port index
1253  * @param[out] value Designated cost of the port
1254  * @return Error code
1255  **/
1256 
1258  uint_t portIndex, uint32_t *value)
1259 {
1261 
1262  //Check parameters
1263  if(context == NULL || value == NULL)
1264  return ERROR_READ_FAILED;
1265 
1266  //Invalid port index?
1267  if(portIndex < 1 || portIndex > context->numPorts)
1268  return ERROR_INVALID_PORT;
1269 
1270  //Point to the port that matches the specified port index
1271  port = &context->ports[portIndex - 1];
1272 
1273  //Retrieve the path cost of the Designated Port of the segment connected
1274  //to this port
1275  *value = port->designatedCost;
1276 
1277  //Successful processing
1278  return NO_ERROR;
1279 }
1280 
1281 
1282 /**
1283  * @brief Get the bridge identifier of the designated bridge
1284  * @param[in] context Pointer to the STP bridge context
1285  * @param[in] portIndex Port index
1286  * @param[out] value Bridge identifier
1287  * @return Error code
1288  **/
1289 
1291  uint_t portIndex, StpBridgeId *value)
1292 {
1294 
1295  //Check parameters
1296  if(context == NULL || value == NULL)
1297  return ERROR_READ_FAILED;
1298 
1299  //Invalid port index?
1300  if(portIndex < 1 || portIndex > context->numPorts)
1301  return ERROR_INVALID_PORT;
1302 
1303  //Point to the port that matches the specified port index
1304  port = &context->ports[portIndex - 1];
1305 
1306  //Retrieve the Bridge Identifier of the bridge that this port considers to
1307  //be the Designated Bridge for this port's segment
1308  *value = port->designatedBridge;
1309 
1310  //Successful processing
1311  return NO_ERROR;
1312 }
1313 
1314 
1315 /**
1316  * @brief Get the port identifier of the designated bridge
1317  * @param[in] context Pointer to the STP bridge context
1318  * @param[in] portIndex Port index
1319  * @param[out] value Port identifier
1320  * @return Error code
1321  **/
1322 
1324  uint_t portIndex, uint16_t *value)
1325 {
1327 
1328  //Check parameters
1329  if(context == NULL || value == NULL)
1330  return ERROR_READ_FAILED;
1331 
1332  //Invalid port index?
1333  if(portIndex < 1 || portIndex > context->numPorts)
1334  return ERROR_INVALID_PORT;
1335 
1336  //Point to the port that matches the specified port index
1337  port = &context->ports[portIndex - 1];
1338 
1339  //Retrieve the Port Identifier of the port on the Designated Bridge for
1340  //this port's segment
1341  *value = port->designatedPort;
1342 
1343  //Successful processing
1344  return NO_ERROR;
1345 }
1346 
1347 
1348 /**
1349  * @brief Get the number of times the port has transitioned to Forwarding state
1350  * @param[in] context Pointer to the STP bridge context
1351  * @param[in] portIndex Port index
1352  * @param[out] value Number of transitions to Forwarding state
1353  * @return Error code
1354  **/
1355 
1357  uint_t portIndex, uint_t *value)
1358 {
1360 
1361  //Check parameters
1362  if(context == NULL || value == NULL)
1363  return ERROR_READ_FAILED;
1364 
1365  //Invalid port index?
1366  if(portIndex < 1 || portIndex > context->numPorts)
1367  return ERROR_INVALID_PORT;
1368 
1369  //Point to the port that matches the specified port index
1370  port = &context->ports[portIndex - 1];
1371 
1372  //Retrieve the number of times this port has transitioned from the Learning
1373  //state to the Forwarding state
1374  *value = port->forwardTransitions;
1375 
1376  //Successful processing
1377  return NO_ERROR;
1378 }
1379 
1380 #endif
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
uint16_t port
Definition: dns_common.h:267
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_PORT
Definition: error.h:104
@ ERROR_WRITE_FAILED
Definition: error.h:221
@ ERROR_WRONG_VALUE
Definition: error.h:123
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_READ_FAILED
Definition: error.h:222
@ ERROR_INCONSISTENT_VALUE
Definition: error.h:124
MacAddr
Definition: ethernet.h:195
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
STP (Spanning Tree Protocol)
#define STP_MAX_AGEING_TIME
Definition: stp.h:167
#define STP_MAX_PORT_PATH_COST
Definition: stp.h:188
#define STP_MAX_BRIDGE_FORWARD_DELAY
Definition: stp.h:139
#define StpBridgeContext
Definition: stp.h:36
#define STP_MAX_BRIDGE_HELLO_TIME
Definition: stp.h:118
#define StpBridgePort
Definition: stp.h:40
#define STP_MAX_BRIDGE_MAX_AGE
Definition: stp.h:97
#define STP_PORT_PRIORITY_MASK
Definition: stp_bpdu.h:42
#define STP_PORT_NUM_MASK
Definition: stp_bpdu.h:43
StpBridgeId
Definition: stp_common.h:148
StpPortRole
Port role values.
Definition: stp_common.h:123
@ STP_PORT_ROLE_ALTERNATE
Definition: stp_common.h:127
@ STP_PORT_ROLE_ROOT
Definition: stp_common.h:125
@ STP_PORT_ROLE_DESIGNATED
Definition: stp_common.h:126
@ STP_PORT_ROLE_DISABLED
Definition: stp_common.h:124
StpPortState
Port states.
Definition: stp_common.h:108
@ STP_PORT_STATE_BLOCKING
Definition: stp_common.h:111
@ STP_PORT_STATE_LEARNING
Definition: stp_common.h:113
@ STP_PORT_STATE_LISTENING
Definition: stp_common.h:112
@ STP_PORT_STATE_BROKEN
Definition: stp_common.h:110
@ STP_PORT_STATE_FORWARDING
Definition: stp_common.h:114
@ STP_PORT_STATE_DISABLED
Definition: stp_common.h:109
bool_t stpRootPort(StpBridgePort *port)
Test whether a given port is the Root port for the bridge.
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.
error_t stpMgmtGetPortRole(StpBridgeContext *context, uint_t portIndex, StpPortRole *value)
Get the assigned role of the port.
Definition: stp_mgmt.c:1171
error_t stpMgmtGetMacOperState(StpBridgeContext *context, uint_t portIndex, bool_t *value)
Get the current MAC operational state.
Definition: stp_mgmt.c:1031
error_t stpMgmtGetTimeSinceTopologyChange(StpBridgeContext *context, uint_t *value)
Get the time since a topology change was last detected.
Definition: stp_mgmt.c:676
error_t stpMgmtGetDesignatedRoot(StpBridgeContext *context, StpBridgeId *value)
Get the bridge identifier of the root of the spanning tree.
Definition: stp_mgmt.c:523
error_t stpMgmtGetBridgePriority(StpBridgeContext *context, uint16_t *value)
Get the assigned bridge priority.
Definition: stp_mgmt.c:397
error_t stpMgmtGetForwardTransitions(StpBridgeContext *context, uint_t portIndex, uint_t *value)
Get the number of times the port has transitioned to Forwarding state.
Definition: stp_mgmt.c:1356
error_t stpMgmtGetHelloTime(StpBridgeContext *context, uint_t *value)
Get the current Hello Time value.
Definition: stp_mgmt.c:610
error_t stpMgmtGetAdminPortState(StpBridgeContext *context, uint_t portIndex, bool_t *value)
Get the administrative port state.
Definition: stp_mgmt.c:999
error_t stpMgmtGetBridgeHelloTime(StpBridgeContext *context, uint_t *value)
Get the assigned value of the Bridge Hello Time parameter.
Definition: stp_mgmt.c:439
error_t stpMgmtSetBridgeHelloTime(StpBridgeContext *context, uint_t value, bool_t commit)
Set Bridge Hello Time parameter.
Definition: stp_mgmt.c:198
error_t stpMgmtGetNumPorts(StpBridgeContext *context, uint_t *value)
Get the number of ports.
Definition: stp_mgmt.c:356
error_t stpMgmtSetBridgeMaxAge(StpBridgeContext *context, uint_t value, bool_t commit)
Set Bridge Max Age parameter.
Definition: stp_mgmt.c:137
error_t stpMgmtGetBridgeMaxAge(StpBridgeContext *context, uint_t *value)
Get the assigned value of the Bridge Max Age parameter.
Definition: stp_mgmt.c:418
error_t stpMgmtGetRootPort(StpBridgeContext *context, uint16_t *value)
Get the current root port.
Definition: stp_mgmt.c:566
error_t stpMgmtGetPortDesignatedPort(StpBridgeContext *context, uint_t portIndex, uint16_t *value)
Get the port identifier of the designated bridge.
Definition: stp_mgmt.c:1323
error_t stpMgmtSetAgeingTime(StpBridgeContext *context, uint_t value, bool_t commit)
Set Ageing Time parameter.
Definition: stp_mgmt.c:314
error_t stpMgmtGetHoldTime(StpBridgeContext *context, uint_t *value)
Get the assigned value of the Hold Time parameter.
Definition: stp_mgmt.c:481
error_t stpMgmtSetBridgePriority(StpBridgeContext *context, uint16_t value, bool_t commit)
Set bridge priority.
Definition: stp_mgmt.c:55
error_t stpMgmtGetPortPriority(StpBridgeContext *context, uint_t portIndex, uint8_t *value)
Get the priority assigned to the port.
Definition: stp_mgmt.c:967
error_t stpMgmtSetBridgeForwardDelay(StpBridgeContext *context, uint_t value, bool_t commit)
Set Bridge Forward Delay parameter.
Definition: stp_mgmt.c:253
error_t stpMgmtGetAgeingTime(StpBridgeContext *context, uint_t *value)
Get the assigned value of the Ageing Time parameter.
Definition: stp_mgmt.c:502
error_t stpMgmtGetBridgeAddr(StpBridgeContext *context, MacAddr *value)
Get the MAC address assigned to the bridge.
Definition: stp_mgmt.c:376
error_t stpMgmtSetAdminPortState(StpBridgeContext *context, uint_t portIndex, bool_t value, bool_t commit)
Set administrative bridge port state.
Definition: stp_mgmt.c:774
error_t stpMgmtGetPortState(StpBridgeContext *context, uint_t portIndex, StpPortState *value)
Get the current state of the port.
Definition: stp_mgmt.c:1096
error_t stpMgmtGetPortDesignatedCost(StpBridgeContext *context, uint_t portIndex, uint32_t *value)
Get the designated cost of the port.
Definition: stp_mgmt.c:1257
error_t stpMgmtGetTopologyChanges(StpBridgeContext *context, uint_t *value)
Get the number of topology changes.
Definition: stp_mgmt.c:655
error_t stpMgmtGetForwardDelay(StpBridgeContext *context, uint_t *value)
Get the current Forward Delay value.
Definition: stp_mgmt.c:633
error_t stpMgmtGetPortAddr(StpBridgeContext *context, uint_t portIndex, MacAddr *value)
Get the MAC address assigned to the port.
Definition: stp_mgmt.c:935
error_t stpMgmtGetPortDesignatedRoot(StpBridgeContext *context, uint_t portIndex, StpBridgeId *value)
Get the bridge identifier of the designated root bridge.
Definition: stp_mgmt.c:1223
error_t stpMgmtGetBridgeForwardDelay(StpBridgeContext *context, uint_t *value)
Get the assigned value of the Bridge Forward Delay parameter.
Definition: stp_mgmt.c:460
error_t stpMgmtSetPortPathCost(StpBridgeContext *context, uint_t portIndex, uint32_t value, bool_t commit)
Set administrative port path cost.
Definition: stp_mgmt.c:886
error_t stpMgmtGetRootPathCost(StpBridgeContext *context, uint32_t *value)
Get the current cost of the path to the root.
Definition: stp_mgmt.c:545
error_t stpMgmtGetMaxAge(StpBridgeContext *context, uint_t *value)
Get the current Max Age value.
Definition: stp_mgmt.c:588
error_t stpMgmtGetPortDesignatedBridge(StpBridgeContext *context, uint_t portIndex, StpBridgeId *value)
Get the bridge identifier of the designated bridge.
Definition: stp_mgmt.c:1290
error_t stpMgmtSetPortPriority(StpBridgeContext *context, uint_t portIndex, uint8_t value, bool_t commit)
Set port priority.
Definition: stp_mgmt.c:702
error_t stpMgmtGetPortPathCost(StpBridgeContext *context, uint_t portIndex, uint32_t *value)
Get the current value of the port path cost.
Definition: stp_mgmt.c:1063
void stpUpdateAgeingTime(StpBridgeContext *context, uint32_t ageingTime)
Set ageing time for dynamic filtering entries.
Definition: stp_misc.c:427
void stpStartTimer(StpTimer *timer, uint_t value)
Start timer.
Definition: stp_misc.c:729
void stpStopTimer(StpTimer *timer)
Stop timer.
Definition: stp_misc.c:743
bool_t stpCheckBridgeParams(uint_t maxAge, uint_t helloTime, uint_t forwardDelay)
Check bridge parameters.
Definition: stp_misc.c:672
void stpUpdatePortState(StpBridgePort *port, StpPortState state)
Set port state.
Definition: stp_misc.c:358
int_t stpCompareBridgeId(const StpBridgeId *id1, const StpBridgeId *id2)
Compare bridge identifiers.
Definition: stp_misc.c:296
STP helper functions.
void stpBecomeDesignatedPort(StpBridgePort *port)
Become Designated port (8.6.10)
void stpTopologyChangeDetection(StpBridgeContext *context)
Topology change detection (8.6.14)
void stpConfigUpdate(StpBridgeContext *context)
Configuration update (8.6.7)
void stpPortStateSelection(StpBridgeContext *context)
Port state selection (8.6.11)
void stpConfigBpduGeneration(StpBridgeContext *context)
Configuration BPDU generation (8.6.4)
Elements of procedures.
uint8_t value[]
Definition: tcp.h:369