rstp_misc.c
Go to the documentation of this file.
1 /**
2  * @file rstp_misc.c
3  * @brief RSTP helper functions
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 RSTP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "rstp/rstp.h"
36 #include "rstp/rstp_fsm.h"
37 #include "rstp/rstp_conditions.h"
38 #include "rstp/rstp_misc.h"
39 #include "debug.h"
40 
41 //Check TCP/IP stack configuration
42 #if (RSTP_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief Acquire exclusive access to the RSTP bridge context
47  * @param[in] context Pointer to the RSTP bridge context
48  **/
49 
51 {
52  //Acquire exclusive access
54 }
55 
56 
57 /**
58  * @brief Release exclusive access to the RSTP bridge context
59  * @param[in] context Pointer to the RSTP bridge context
60  **/
61 
63 {
64  //Release exclusive access
66 }
67 
68 
69 /**
70  * @brief RSTP tick handler
71  *
72  * This routine must be called at one second intervals
73  *
74  * @param[in] context Pointer to the RSTP bridge context
75  **/
76 
78 {
79  uint_t i;
80  bool_t macOperState;
82  NetInterface *interface;
83 
84  //Make sure the RSTP bridge context is valid
85  if(context != NULL)
86  {
87  //Point to the underlying network interface
88  interface = context->interface;
89 
90  //Any topology change detected?
91  if(context->topologyChangeCount > 0)
92  {
93  //Increment the count in seconds of the time since the tcWhile timer
94  //for any port was non-zero
95  context->timeSinceTopologyChange++;
96  }
97 
98  //Decrement the rapid ageing timer
99  rstpDecrementTimer(&context->rapidAgeingWhile);
100 
101  //Check whether the value of the timer is zero
102  if(context->rapidAgeingWhile == 0)
103  {
104  //Determine whether the short (Forward Delay) or long (Ageing Time)
105  //timeout value is to be used for dynamic entries in the filtering
106  //database
107  if(context->ageingTime != context->params.ageingTime)
108  {
109  //Restore long timeout value
110  context->ageingTime = context->params.ageingTime;
111  //Set ageing time for dynamic filtering entries
112  rstpUpdateAgeingTime(context, context->ageingTime);
113  }
114  }
115 
116  //Loop through the ports of the bridge
117  for(i = 0; i < context->numPorts; i++)
118  {
119  //Point to the current bridge port
120  port = &context->ports[i];
121 
122  //The tick signal is set by an implementation specific system clock
123  //function at one second intervals
124  port->tick = TRUE;
125 
126  //Valid switch driver?
127  if(interface->switchDriver != NULL &&
128  interface->switchDriver->getLinkState != NULL &&
129  interface->switchDriver->getLinkSpeed != NULL &&
130  interface->switchDriver->getDuplexMode != NULL)
131  {
132  //Poll link state
133  macOperState = interface->switchDriver->getLinkState(interface, i + 1);
134 
135  //Link state change detected?
136  if(macOperState && !port->macOperState && interface->linkState)
137  {
138  //Debug message
139  TRACE_INFO("Port %" PRIu8 ": Link is up...\r\n", port->portIndex);
140 
141  //The port is up
142  port->macOperState = TRUE;
143 
144  //Retrieve link speed and duplex mode
145  port->linkSpeed = interface->switchDriver->getLinkSpeed(interface, i + 1);
146  port->duplexMode = interface->switchDriver->getDuplexMode(interface, i + 1);
147 
148  //Recalculate the contribution of the port to the root path cost
150 
151  //The MAC is considered to be connected to a point-to-point LAN
152  //if the MAC entity is configured for full duplex operation
154  }
155  else if(!macOperState && port->macOperState)
156  {
157  //Debug message
158  TRACE_INFO("Port %" PRIu8 ": Link is down...\r\n", port->portIndex);
159 
160  //The port is down
161  port->macOperState = FALSE;
162  }
163  else
164  {
165  //No link state change
166  }
167  }
168 
169  //The portEnabled variable is set if the MAC entity can transmit and
170  //receive frames to and from the attached LAN
171  port->portEnabled = port->macOperState && port->params.adminPortState;
172  }
173 
174  //Update RSTP state machine
175  rstpFsm(context);
176  }
177 }
178 
179 
180 /**
181  * @brief Retrieve the port that matches the specified port number
182  * @param[in] context Pointer to the RSTP bridge context
183  * @param[in] portId Port identifier
184  * @return Pointer to the matching port, if any
185  **/
186 
188 {
189  uint_t i;
191 
192  //Initialize pointer
193  port = NULL;
194 
195  //Loop through the ports of the bridge
196  for(i = 0; i < context->numPorts; i++)
197  {
198  //Check port number
199  if(rstpComparePortNum(context->ports[i].portId, portId) == 0)
200  {
201  port = &context->ports[i];
202  break;
203  }
204  }
205 
206  //Return a pointer to the matching port, if any
207  return port;
208 }
209 
210 
211 /**
212  * @brief Compare port numbers
213  * @param[in] portId1 First port identifier
214  * @param[in] portId2 Second port identifier
215  * @return The function returns zero if the port numbers are the same and a
216  * non-zero value if the port numbers are different
217  **/
218 
219 int_t rstpComparePortNum(uint16_t portId1, uint16_t portId2)
220 {
221  int_t res;
222  uint16_t portNum1;
223  uint16_t portNum2;
224 
225  //The less significant twelve bits is the port number
226  portNum1 = portId1 & RSTP_PORT_NUM_MASK;
227  portNum2 = portId2 & RSTP_PORT_NUM_MASK;
228 
229  //Compare port numbers
230  if(portNum1 < portNum2)
231  {
232  res = -1;
233  }
234  else if(portNum1 > portNum2)
235  {
236  res = 1;
237  }
238  else
239  {
240  res = 0;
241  }
242 
243  //Return comparison result
244  return res;
245 }
246 
247 
248 /**
249  * @brief Compare bridge addresses
250  * @param[in] addr1 First bridge address
251  * @param[in] addr2 Second bridge address
252  * @return The function returns 1 if addr1 is greater than addr2, 0 if addr1
253  * is the same as addr2 and -1 if addr1 is less than addr2
254  **/
255 
256 int_t rstpCompareBridgeAddr(const MacAddr *addr1, const MacAddr *addr2)
257 {
258  //Compare bridge addresses
259  return osMemcmp(addr1, addr2, sizeof(MacAddr));
260 }
261 
262 
263 /**
264  * @brief Compare bridge identifiers
265  * @param[in] id1 First bridge identifier
266  * @param[in] id2 Second bridge identifier
267  * @return The function returns 1 if id1 is greater than id2, 0 if id1
268  * is the same as id2 and -1 if id1 is less than id2
269  **/
270 
272 {
273  int_t res;
274 
275  //Compare bridge identifiers
276  if(id1->priority < id2->priority)
277  {
278  res = -1;
279  }
280  else if(id1->priority > id2->priority)
281  {
282  res = 1;
283  }
284  else
285  {
286  res = rstpCompareBridgeAddr(&id1->addr, &id2->addr);
287  }
288 
289  //Return comparison result
290  return res;
291 }
292 
293 
294 /**
295  * @brief Compare priority vectors
296  * @param[in] p1 First priority vector
297  * @param[in] p2 Second priority vector
298  * @return The function returns 1 if p1 priority is better than p2, 0 if p1
299  * priority is the same as p2 and -1 if p1 priority is worse than p2
300  **/
301 
303 {
304  int_t res;
305 
306  //Compare priority vectors according to 17.6 rules
307  if(rstpCompareBridgeId(&p1->rootBridgeId, &p2->rootBridgeId) < 0)
308  {
309  res = 1;
310  }
311  else if(rstpCompareBridgeId(&p1->rootBridgeId, &p2->rootBridgeId) > 0)
312  {
313  res = -1;
314  }
315  else if(p1->rootPathCost < p2->rootPathCost)
316  {
317  res = 1;
318  }
319  else if(p1->rootPathCost > p2->rootPathCost)
320  {
321  res = -1;
322  }
324  &p2->designatedBridgeId) < 0)
325  {
326  res = 1;
327  }
329  &p2->designatedBridgeId) > 0)
330  {
331  res = -1;
332  }
333  else if(p1->designatedPortId < p2->designatedPortId)
334  {
335  res = 1;
336  }
337  else if(p1->designatedPortId > p2->designatedPortId)
338  {
339  res = -1;
340  }
341  else if(p1->bridgePortId < p2->bridgePortId)
342  {
343  res = 1;
344  }
345  else if(p1->bridgePortId > p2->bridgePortId)
346  {
347  res = -1;
348  }
349  else
350  {
351  res = 0;
352  }
353 
354  //Return comparison result
355  return res;
356 }
357 
358 
359 /**
360  * @brief Compare timer parameter values
361  * @param[in] t1 First set of timer values
362  * @param[in] t2 Second set of timer values
363  * @return The function returns 1 if t1 differs from t2 and 0 if t1 is the
364  * same as t2
365  **/
366 
368 {
369  int_t res = 0;
370 
371  //Check whether t1 timer values are the same as t2 timer values
372  if(t1->messageAge == t2->messageAge &&
373  t1->maxAge == t2->maxAge &&
374  t1->forwardDelay == t2->forwardDelay &&
375  t1->helloTime == t2->helloTime)
376  {
377  res = 0;
378  }
379  else
380  {
381  res = 1;
382  }
383 
384  //Return comparison result
385  return res;
386 }
387 
388 
389 /**
390  * @brief Update the number of topology changes
391  * @param[in] context Pointer to the RSTP bridge context
392  **/
393 
395 {
396  uint_t i;
397  bool_t flag;
398 
399  //Check whether the tcWhile variable is zero for all the ports
400  for(flag = TRUE, i = 0; i < context->numPorts; i++)
401  {
402  //Check the value of the tcWhile timer for the current port
403  if(context->ports[i].tcWhile != 0)
404  {
405  flag = FALSE;
406  }
407  }
408 
409  //Any topology change detected?
410  if(flag)
411  {
412  //Increment the number of topology changes
413  context->topologyChangeCount++;
414  //Reset the time since the last topology change
415  context->timeSinceTopologyChange = 0;
416  }
417 }
418 
419 
420 /**
421  * @brief Update the value of the portPathCost variable
422  * @param[in] port Pointer to the bridge port context
423  **/
424 
426 {
427  //An administrative value of zero assigns the automatically calculated
428  //default Path Cost value to the port
429  if(port->params.adminPathCost == 0)
430  {
431  //The value of the Port Path Cost variable is chosen according to the
432  //speed of the attached LAN
433  if(port->linkSpeed <= 100000)
434  {
435  port->portPathCost = 200000000;
436  }
437  else
438  {
439  port->portPathCost = 200000000 / (port->linkSpeed / 100000);
440  }
441  }
442  else
443  {
444  //Update the value of the Port Path Cost
445  port->portPathCost = port->params.adminPathCost;
446  }
447 }
448 
449 
450 /**
451  * @brief Update the value of the operPointToPointMac variable
452  * @param[in] port Pointer to the bridge port context
453  **/
454 
456 {
457  //Check the administrative point-to-point status of the LAN segment attached
458  //to this port
459  if(port->params.adminPointToPointMac == RSTP_ADMIN_P2P_MAC_AUTO)
460  {
461  //The MAC is considered to be connected to a point-to-point LAN if the
462  //MAC entity is configured for full duplex operation
463  if(port->duplexMode == NIC_FULL_DUPLEX_MODE)
464  {
465  port->operPointToPointMac = TRUE;
466  }
467  else
468  {
469  port->operPointToPointMac = FALSE;
470  }
471  }
472  else if(port->params.adminPointToPointMac == RSTP_ADMIN_P2P_MAC_FORCE_TRUE)
473  {
474  //The administrator requires the MAC to be treated as if it is connected
475  //to a point-to-point LAN, regardless of any indications to the contrary
476  //that are generated by the MAC entity
477  port->operPointToPointMac = TRUE;
478  }
479  else
480  {
481  //The administrator requires the MAC to be treated as connected to a
482  //non-point-to-point LAN, regardless of any indications to the contrary
483  //that are generated by the MAC entity
484  port->operPointToPointMac = FALSE;
485  }
486 }
487 
488 
489 /**
490  * @brief Set port state
491  * @param[in] port Pointer to the bridge port context
492  * @param[in] state Port state (disabled, learning or forwarding)
493  **/
494 
496 {
497  NetInterface *interface;
498  RstpBridgeContext *context;
499 
500  //Point to the RSTP bridge context
501  context = port->context;
502 
503  //Check RSTP bridge operation state
504  if(context->running)
505  {
506  //Point to the underlying network interface
507  interface = context->interface;
508 
509  //Valid switch driver?
510  if(interface->switchDriver != NULL &&
511  interface->switchDriver->setPortState != NULL)
512  {
513  //Update the state of the specified port
514  interface->switchDriver->setPortState(interface, port->portIndex,
515  state);
516  }
517  }
518 }
519 
520 
521 /**
522  * @brief Set ageing time for dynamic filtering entries
523  * @param[in] context Pointer to the RSTP bridge context
524  * @param[in] ageingTime Aging time, in seconds
525  **/
526 
527 void rstpUpdateAgeingTime(RstpBridgeContext *context, uint32_t ageingTime)
528 {
529  NetInterface *interface;
530 
531  //Debug message
532  TRACE_INFO("Set ageing time to %" PRIu32 " seconds...\r\n", ageingTime);
533 
534  //Check RSTP bridge operation state
535  if(context->running)
536  {
537  //Point to the underlying network interface
538  interface = context->interface;
539 
540  //Valid switch driver?
541  if(interface->switchDriver != NULL &&
542  interface->switchDriver->setAgingTime != NULL)
543  {
544  //Set ageing time for dynamic filtering entries
545  interface->switchDriver->setAgingTime(interface, ageingTime);
546  }
547  }
548 }
549 
550 
551 /**
552  * @brief Enable reserved multicast table
553  * @param[in] context Pointer to the RSTP bridge context
554  * @param[in] enable Enable or disable reserved group addresses
555  **/
556 
558 {
559  NetInterface *interface;
560 
561  //Point to the underlying network interface
562  interface = context->interface;
563 
564  //Valid switch driver?
565  if(interface->switchDriver != NULL &&
566  interface->switchDriver->enableRsvdMcastTable != NULL)
567  {
568  //Enable or disable reserved group addresses
569  interface->switchDriver->enableRsvdMcastTable(interface, enable);
570  }
571 }
572 
573 
574 /**
575  * @brief Add a new entry to the static MAC table
576  * @param[in] context Pointer to the RSTP bridge context
577  * @param[in] macAddr MAC address to be added
578  * @param[in] override This flag specifies whether packets received with a
579  * destination address that matches the MAC address will be forwarded
580  * regardless of the port state
581  * @return Error code
582  **/
583 
585  bool_t override)
586 {
587  error_t error;
588  SwitchFdbEntry entry;
589  NetInterface *interface;
590 
591  //Initialize status code
592  error = NO_ERROR;
593 
594  //Point to the underlying network interface
595  interface = context->interface;
596 
597  //Valid switch driver?
598  if(interface->switchDriver != NULL &&
599  interface->switchDriver->addStaticFdbEntry != NULL)
600  {
601  //Format forwarding database entry
602  entry.macAddr = *macAddr;
603  entry.srcPort = 0;
605  entry.override = override;
606 
607  //Update the static MAC table of the switch
608  error = interface->switchDriver->addStaticFdbEntry(interface, &entry);
609  }
610 
611  //Return status code
612  return error;
613 }
614 
615 
616 /**
617  * @brief Remove an entry from the static MAC table
618  * @param[in] context Pointer to the RSTP bridge context
619  * @param[in] macAddr MAC address to be removed from the table
620  * @return Error code
621  **/
622 
624  const MacAddr *macAddr)
625 {
626  error_t error;
627  SwitchFdbEntry entry;
628  NetInterface *interface;
629 
630  //Initialize status code
631  error = NO_ERROR;
632 
633  //Point to the underlying network interface
634  interface = context->interface;
635 
636  //Valid switch driver?
637  if(interface->switchDriver != NULL &&
638  interface->switchDriver->deleteStaticFdbEntry != NULL)
639  {
640  //Format forwarding database entry
641  entry.macAddr = *macAddr;
642  entry.srcPort = 0;
643  entry.destPorts = 0;
644  entry.override = FALSE;
645 
646  //Update the static MAC table of the switch
647  error = interface->switchDriver->deleteStaticFdbEntry(interface, &entry);
648  }
649 
650  //Return status code
651  return error;
652 }
653 
654 
655 /**
656  * @brief Remove filtering database entries (immediately or by rapid ageing)
657  * @param[in] port Pointer to the bridge port context
658  **/
659 
661 {
662  uint_t value;
663  RstpBridgeContext *context;
664 
665  //Point to the RSTP bridge context
666  context = port->context;
667 
668  //Check whether the bridge is operating in STP compatibility mode
669  if(stpVersion(context))
670  {
671  //Save the current value of the ageingTime parameter
672  value = context->ageingTime;
673 
674  //The value of the ageingTime parameter is changed to FwdDelay for a
675  //period of FwdDelay after fdbFlush is set by the topology change state
676  //machine if stpVersion is TRUE
677  context->ageingTime = rstpFwdDelay(port);
678  context->rapidAgeingWhile = rstpFwdDelay(port);
679 
680  //Instruct the filtering database to remove all entries for this port
681  //by rapid ageing
682  if(context->ageingTime != value)
683  {
684  rstpUpdateAgeingTime(context, context->ageingTime);
685  }
686 
687  //The fdbFlush flag is reset immediately
688  port->fdbFlush = FALSE;
689  }
690  else
691  {
692  //Instruct the filtering database to remove all entries for this port
693  //immediately if rstpVersion is TRUE
695 
696  //The fdbFlush flag is reset by the filtering database once the entries
697  //are removed
698  port->fdbFlush = FALSE;
699  }
700 
701  //The RSTP state machine is busy
702  context->busy = TRUE;
703 }
704 
705 
706 /**
707  * @brief Remove all the filtering database entries for a given port
708  * @param[in] port Pointer to the bridge port context
709  **/
710 
712 {
713  NetInterface *interface;
714  RstpBridgeContext *context;
715 
716  //Point to the RSTP bridge context
717  context = port->context;
718 
719  //Point to the underlying network interface
720  interface = context->interface;
721 
722  //Debug message
723  TRACE_INFO("Port %" PRIu8 ": Flush filtering database...\r\n",
724  port->portIndex);
725 
726  //Valid switch driver?
727  if(interface->switchDriver != NULL &&
728  interface->switchDriver->flushDynamicFdbTable != NULL)
729  {
730  //Flush the filtering database
731  interface->switchDriver->flushDynamicFdbTable(interface,
732  port->portIndex);
733  }
734 }
735 
736 
737 /**
738  * @brief Configure the permanent database
739  * @param[in] context Pointer to the RSTP bridge context
740  * @return Error code
741  **/
742 
744 {
745  uint_t i;
746  error_t error;
747 
748  //The Bridge Group Address shall be configured in the permanent database in
749  //order to confine BPDUs to the individual LAN on which they are transmitted
750  //(refer IEEE Std 802.1D-2004, section 7.12.3)
752 
753  //Check status code
754  if(!error)
755  {
756  //Add the bridge's address to the static MAC table of the switch
757  error = rstpAddStaticFdbEntry(context, &context->bridgeId.addr, FALSE);
758  }
759 
760  //Frames addressed to a bridge port as an end station shall be submitted to
761  //LLC (refer IEEE Std 802.1D-2004, section 7.5)
762  for(i = 0; i < context->numPorts && !error; i++)
763  {
764  //Add the port's address to the static MAC table of the switch
765  error = rstpAddStaticFdbEntry(context, &context->ports[i].macAddr, FALSE);
766  }
767 
768  //Check status code
769  if(!error)
770  {
771  //Frames containing any of the reserved addresses in their destination
772  //address field shall not be relayed by the bridge. They shall be
773  //configured in the permanent database (refer IEEE Std 802.1D-2004,
774  //section 7.12.6)
775  rstpEnableRsvdMcastTable(context, TRUE);
776  }
777 
778  //Return status code
779  return error;
780 }
781 
782 
783 /**
784  * @brief Unconfigure the permanent database
785  * @param[in] context Pointer to the RSTP bridge context
786  **/
787 
789 {
790  uint_t i;
791 
792  //Remove the Bridge Group Address from the static MAC table of the switch
794 
795  //Remove the bridge's address from the static MAC table of the switch
796  rstpDeleteStaticFdbEntry(context, &context->bridgeId.addr);
797 
798  //Loop through the ports of the bridge
799  for(i = 0; i < context->numPorts; i++)
800  {
801  //Remove the port's address from the static MAC table of the switch
802  rstpDeleteStaticFdbEntry(context, &context->ports[i].macAddr);
803  }
804 
805  //Remove reserved group addresses from the permanent database
807 }
808 
809 
810 /**
811  * @brief Port's MAC address generation
812  * @param[in] port Pointer to the bridge port context
813  **/
814 
816 {
817  int_t i;
818  uint8_t c;
819  MacAddr *bridgeAddr;
820 
821  //Get bridge's MAC address
822  bridgeAddr = &port->context->bridgeId.addr;
823 
824  //Retrieve port index
825  c = port->portIndex;
826 
827  //Generate a unique MAC address for the port
828  for(i = 5; i >= 0; i--)
829  {
830  //Generate current byte
831  port->macAddr.b[i] = bridgeAddr->b[i] + c;
832 
833  //Propagate the carry if necessary
834  if(port->macAddr.b[i] < bridgeAddr->b[i])
835  {
836  c = 1;
837  }
838  else
839  {
840  c = 0;
841  }
842  }
843 }
844 
845 
846 /**
847  * @brief Check bridge parameters
848  * @param[in] maxAge Value of the Bridge Max Age parameter
849  * @param[in] helloTime Value of the Bridge Hello Time parameter
850  * @param[in] forwardDelay Value of the Bridge Forward Delay parameter
851  * @return TRUE if the set of parameters is valid, else FALSE
852  **/
853 
856 {
857  bool_t valid;
858 
859  //To support interoperability with legacy bridges, a bridge shall enforce the
860  //following relationships (refer to IEEE Std 802.1D-2004, section 17.14)
861  if(maxAge >= (2 * (helloTime + 1)) && maxAge <= (2 * (forwardDelay - 1)))
862  {
863  valid = TRUE;
864  }
865  else
866  {
867  valid = FALSE;
868  }
869 
870  //Return TRUE if the set of parameters is valid, else FALSE
871  return valid;
872 }
873 
874 
875 /**
876  * @brief Convert a parameter to string representation
877  * @param[in] value Parameter value
878  * @param[in] paramList List of acceptable parameters
879  * @param[in] paramListLen Number of entries in the list
880  * @return NULL-terminated string describing the parameter
881  **/
882 
884  size_t paramListLen)
885 {
886  uint_t i;
887 
888  //Default name for unknown values
889  static const char_t defaultName[] = "Unknown";
890 
891  //Loop through the list of acceptable parameters
892  for(i = 0; i < paramListLen; i++)
893  {
894  if(paramList[i].value == value)
895  {
896  return paramList[i].name;
897  }
898  }
899 
900  //Unknown value
901  return defaultName;
902 }
903 
904 
905 /**
906  * @brief Decrement timer value
907  * @param[in,out] x Actual timer value
908  **/
909 
911 {
912  //Non-zero timer value?
913  if(*x > 0)
914  {
915  //Decrement timer value
916  *x -= 1;
917  }
918 }
919 
920 #endif
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
uint32_t t1
uint32_t t2
uint16_t port
Definition: dns_common.h:267
error_t
Error codes.
Definition: error.h:43
@ NO_ERROR
Success.
Definition: error.h:44
MacAddr
Definition: ethernet.h:195
uint8_t x
Definition: lldp_ext_med.h:211
uint8_t portId[]
Definition: lldp_tlv.h:254
uint8_t c
Definition: ndp.h:514
#define NetInterface
Definition: net.h:36
#define netMutex
Definition: net_legacy.h:195
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
#define SWITCH_CPU_PORT_MASK
Definition: nic.h:60
SwitchPortState
Switch port state.
Definition: nic.h:134
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
const uint8_t res[]
RSTP (Rapid Spanning Tree Protocol)
@ RSTP_ADMIN_P2P_MAC_AUTO
Definition: rstp.h:258
@ RSTP_ADMIN_P2P_MAC_FORCE_TRUE
Definition: rstp.h:257
#define RstpBridgeContext
Definition: rstp.h:36
#define RstpBridgePort
Definition: rstp.h:40
const MacAddr RSTP_BRIDGE_GROUP_ADDR
Definition: rstp_bpdu.c:46
#define RSTP_PORT_NUM_MASK
Definition: rstp_bpdu.h:44
uint16_t forwardDelay
Definition: rstp_bpdu.h:109
uint16_t helloTime
Definition: rstp_bpdu.h:108
uint16_t maxAge
Definition: rstp_bpdu.h:107
uint_t rstpFwdDelay(RstpBridgePort *port)
FwdDelay variable evaluation (17.20.6)
bool_t stpVersion(RstpBridgeContext *context)
stpVersion condition (17.20.12)
RSTP state machine conditions.
void rstpFsm(RstpBridgeContext *context)
RSTP state machine implementation.
Definition: rstp_fsm.c:152
Rapid Spanning Tree state machines.
void rstpUpdateTopologyChangeCount(RstpBridgeContext *context)
Update the number of topology changes.
Definition: rstp_misc.c:394
void rstpUpdatePortState(RstpBridgePort *port, SwitchPortState state)
Set port state.
Definition: rstp_misc.c:495
int_t rstpComparePortNum(uint16_t portId1, uint16_t portId2)
Compare port numbers.
Definition: rstp_misc.c:219
RstpBridgePort * rstpGetBridgePort(RstpBridgeContext *context, uint16_t portId)
Retrieve the port that matches the specified port number.
Definition: rstp_misc.c:187
void rstpDecrementTimer(uint_t *x)
Decrement timer value.
Definition: rstp_misc.c:910
void rstpFlushFdbTable(RstpBridgePort *port)
Remove all the filtering database entries for a given port.
Definition: rstp_misc.c:711
void rstpEnableRsvdMcastTable(RstpBridgeContext *context, bool_t enable)
Enable reserved multicast table.
Definition: rstp_misc.c:557
const char_t * rstpGetParamName(uint_t value, const RstpParamName *paramList, size_t paramListLen)
Convert a parameter to string representation.
Definition: rstp_misc.c:883
bool_t rstpCheckBridgeParams(uint_t maxAge, uint_t helloTime, uint_t forwardDelay)
Check bridge parameters.
Definition: rstp_misc.c:854
void rstpLock(RstpBridgeContext *context)
Acquire exclusive access to the RSTP bridge context.
Definition: rstp_misc.c:50
int_t rstpComparePriority(const RstpPriority *p1, const RstpPriority *p2)
Compare priority vectors.
Definition: rstp_misc.c:302
error_t rstpAddStaticFdbEntry(RstpBridgeContext *context, const MacAddr *macAddr, bool_t override)
Add a new entry to the static MAC table.
Definition: rstp_misc.c:584
int_t rstpCompareBridgeAddr(const MacAddr *addr1, const MacAddr *addr2)
Compare bridge addresses.
Definition: rstp_misc.c:256
void rstpGeneratePortAddr(RstpBridgePort *port)
Port's MAC address generation.
Definition: rstp_misc.c:815
void rstpRemoveFdbEntries(RstpBridgePort *port)
Remove filtering database entries (immediately or by rapid ageing)
Definition: rstp_misc.c:660
error_t rstpConfigurePermanentDatabase(RstpBridgeContext *context)
Configure the permanent database.
Definition: rstp_misc.c:743
void rstpUnlock(RstpBridgeContext *context)
Release exclusive access to the RSTP bridge context.
Definition: rstp_misc.c:62
void rstpUpdateAgeingTime(RstpBridgeContext *context, uint32_t ageingTime)
Set ageing time for dynamic filtering entries.
Definition: rstp_misc.c:527
int_t rstpCompareBridgeId(const StpBridgeId *id1, const StpBridgeId *id2)
Compare bridge identifiers.
Definition: rstp_misc.c:271
int_t rstpCompareTimes(const RstpTimes *t1, const RstpTimes *t2)
Compare timer parameter values.
Definition: rstp_misc.c:367
error_t rstpDeleteStaticFdbEntry(RstpBridgeContext *context, const MacAddr *macAddr)
Remove an entry from the static MAC table.
Definition: rstp_misc.c:623
void rstpUpdateOperPointToPointMac(RstpBridgePort *port)
Update the value of the operPointToPointMac variable.
Definition: rstp_misc.c:455
void rstpUpdatePortPathCost(RstpBridgePort *port)
Update the value of the portPathCost variable.
Definition: rstp_misc.c:425
void rstpTick(RstpBridgeContext *context)
RSTP tick handler.
Definition: rstp_misc.c:77
void rstpUnconfigurePermanentDatabase(RstpBridgeContext *context)
Unconfigure the permanent database.
Definition: rstp_misc.c:788
RSTP helper functions.
StpBridgeId
Definition: stp_common.h:148
Parameter value/name binding.
Definition: rstp_misc.h:48
const char_t * name
Definition: rstp_misc.h:50
Spanning Tree priority vector.
Definition: rstp.h:280
uint16_t designatedPortId
Definition: rstp.h:284
StpBridgeId rootBridgeId
Definition: rstp.h:281
uint16_t bridgePortId
Definition: rstp.h:285
StpBridgeId designatedBridgeId
Definition: rstp.h:283
uint32_t rootPathCost
Definition: rstp.h:282
RSTP timer parameter values.
Definition: rstp.h:267
Forwarding database entry.
Definition: nic.h:149
MacAddr macAddr
Definition: nic.h:150
uint32_t destPorts
Definition: nic.h:152
bool_t override
Definition: nic.h:153
uint8_t srcPort
Definition: nic.h:151
uint8_t value[]
Definition: tcp.h:369