stp_misc.c
Go to the documentation of this file.
1 /**
2  * @file stp_misc.c
3  * @brief STP 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 STP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "stp/stp.h"
36 #include "stp/stp_operation.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 //STP port states
45 {
46  {STP_PORT_STATE_DISABLED, "Disabled"},
47  {STP_PORT_STATE_LISTENING, "Listening"},
48  {STP_PORT_STATE_LEARNING, "Learning"},
49  {STP_PORT_STATE_FORWARDING, "Forwarding"},
50  {STP_PORT_STATE_BLOCKING, "Blocking"}
51 };
52 
53 
54 /**
55  * @brief Acquire exclusive access to the STP bridge context
56  * @param[in] context Pointer to the STP bridge context
57  **/
58 
59 void stpLock(StpBridgeContext *context)
60 {
61  //Acquire exclusive access
63 }
64 
65 
66 /**
67  * @brief Release exclusive access to the STP bridge context
68  * @param[in] context Pointer to the STP bridge context
69  **/
70 
72 {
73  //Release exclusive access
75 }
76 
77 
78 /**
79  * @brief STP tick handler
80  *
81  * This routine must be called at one second intervals
82  *
83  * @param[in] context Pointer to the STP bridge context
84  **/
85 
86 void stpTick(StpBridgeContext *context)
87 {
88  uint_t i;
89  bool_t macOperState;
91  NetInterface *interface;
92 
93  //Make sure the STP bridge context is valid
94  if(context != NULL)
95  {
96  //Point to the underlying network interface
97  interface = context->interface;
98 
99  //Any topology change detected?
100  if(context->topologyChangeCount > 0)
101  {
102  //Increment the count in seconds of the time since the tcWhile timer
103  //for any port was non-zero
104  context->timeSinceTopologyChange++;
105  }
106 
107  //Loop through the ports of the bridge
108  for(i = 0; i < context->numPorts; i++)
109  {
110  //Point to the current bridge port
111  port = &context->ports[i];
112 
113  //Valid switch driver?
114  if(interface->switchDriver != NULL &&
115  interface->switchDriver->getLinkState != NULL)
116  {
117  //Poll link state
118  macOperState = interface->switchDriver->getLinkState(interface, i + 1);
119 
120  //Link state change detected?
121  if(macOperState && !port->macOperState && interface->linkState)
122  {
123  //Debug message
124  TRACE_INFO("Port %" PRIu8 ": Link is up...\r\n", port->portIndex);
125 
126  //The port is up
127  port->macOperState = TRUE;
128  }
129  else if(!macOperState && port->macOperState)
130  {
131  //Debug message
132  TRACE_INFO("Port %" PRIu8 ": Link is down...\r\n", port->portIndex);
133 
134  //The port is down
135  port->macOperState = FALSE;
136  }
137  else
138  {
139  //No link state change
140  }
141  }
142  }
143 
144  //Increment the Hello Timer and check for expiration
145  if(stpIncrementTimer(&context->helloTimer, context->helloTime))
146  {
147  stpHelloTimerExpiry(context);
148  }
149 
150  //Increment the Topology Change Notification Timer and check for
151  //expiration
152  if(stpIncrementTimer(&context->tcnTimer, context->bridgeHelloTime))
153  {
154  stpTcnTimerExpiry(context);
155  }
156 
157  //Increment the Topology Change Timer and check for expiration
158  if(stpIncrementTimer(&context->topologyChangeTimer, context->topologyChangeTime))
159  {
161  }
162 
163  //Loop through the ports of the bridge
164  for(i = 0; i < context->numPorts; i++)
165  {
166  //Point to the current bridge port
167  port = &context->ports[i];
168 
169  //Increment the Message Age Timer and check for expiration
170  if(stpIncrementTimer(&port->messageAgeTimer, context->maxAge))
171  {
173  }
174  }
175 
176  //Loop through the ports of the bridge
177  for(i = 0; i < context->numPorts; i++)
178  {
179  //Point to the current bridge port
180  port = &context->ports[i];
181 
182  //Increment the Forward Delay Timer and check for expiration
183  if(stpIncrementTimer(&port->forwardDelayTimer, context->forwardDelay))
184  {
186  }
187 
188  //Increment the Hold Timer and check for expiration
189  if(stpIncrementTimer(&port->holdTimer, context->holdTime))
190  {
192  }
193  }
194  }
195 
196  //Increment the rapid ageing timer and check for expiration
197  if(stpIncrementTimer(&context->rapidAgeingTimer, context->forwardDelay))
198  {
199  //Use long ageing time for dynamic filtering entries
200  stpUpdateAgeingTime(context, context->ageingTime);
201  }
202 }
203 
204 
205 /**
206  * @brief Retrieve the port that matches the specified port number
207  * @param[in] context Pointer to the STP bridge context
208  * @param[in] portId Port identifier
209  * @return Pointer to the matching port, if any
210  **/
211 
213 {
214  uint_t i;
216 
217  //Initialize pointer
218  port = NULL;
219 
220  //Loop through the ports of the bridge
221  for(i = 0; i < context->numPorts; i++)
222  {
223  //Check port number
224  if(stpComparePortNum(context->ports[i].portId, portId) == 0)
225  {
226  port = &context->ports[i];
227  break;
228  }
229  }
230 
231  //Return a pointer to the matching port, if any
232  return port;
233 }
234 
235 
236 /**
237  * @brief Compare port numbers
238  * @param[in] portId1 First port identifier
239  * @param[in] portId2 Second port identifier
240  * @return The function returns zero if the port numbers are the same and a
241  * non-zero value if the port numbers are different
242  **/
243 
244 int_t stpComparePortNum(uint16_t portId1, uint16_t portId2)
245 {
246  int_t res;
247  uint16_t portNum1;
248  uint16_t portNum2;
249 
250  //The less significant twelve bits is the port number
251  portNum1 = portId1 & STP_PORT_NUM_MASK;
252  portNum2 = portId2 & STP_PORT_NUM_MASK;
253 
254  //Compare port numbers
255  if(portNum1 < portNum2)
256  {
257  res = -1;
258  }
259  else if(portNum1 > portNum2)
260  {
261  res = 1;
262  }
263  else
264  {
265  res = 0;
266  }
267 
268  //Return comparison result
269  return res;
270 }
271 
272 
273 /**
274  * @brief Compare bridge addresses
275  * @param[in] addr1 First bridge address
276  * @param[in] addr2 Second bridge address
277  * @return The function returns 1 if addr1 is greater than addr2, 0 if addr1
278  * is the same as addr2 and -1 if addr1 is less than addr2
279  **/
280 
281 int_t stpCompareBridgeAddr(const MacAddr *addr1, const MacAddr *addr2)
282 {
283  //Compare bridge addresses
284  return osMemcmp(addr1, addr2, sizeof(MacAddr));
285 }
286 
287 
288 /**
289  * @brief Compare bridge identifiers
290  * @param[in] id1 First bridge identifier
291  * @param[in] id2 Second bridge identifier
292  * @return The function returns 1 if id1 is greater than id2, 0 if id1
293  * is the same as id2 and -1 if id1 is less than id2
294  **/
295 
297 {
298  int_t res;
299 
300  //Compare bridge identifiers
301  if(id1->priority < id2->priority)
302  {
303  res = -1;
304  }
305  else if(id1->priority > id2->priority)
306  {
307  res = 1;
308  }
309  else
310  {
311  res = stpCompareBridgeAddr(&id1->addr, &id2->addr);
312  }
313 
314  //Return comparison result
315  return res;
316 }
317 
318 
319 /**
320  * @brief Set the Topology Change flag
321  * @param[in] context Pointer to the STP bridge context
322  * @param[in] value Value of the Topology Change flag
323  **/
324 
326 {
327  //The Topology Change Count parameters counts the number of times the
328  //Topology Change flag parameter for the bridge has transitioned from FALSE
329  //to TRUE since the bridge was powered on or initialized (refer to IEEE Std
330  //802.1D-1998, section 14.8.1.1.3)
331  if(!context->topologyChange && value)
332  {
333  //Increment the number of topology changes
334  context->topologyChangeCount++;
335  //Reset the time since the last topology change
336  context->timeSinceTopologyChange = 0;
337 
338  //After any topology change, the bridge uses a short value to age out
339  //dynamic entries in the filtering database for a period (refer to IEEE
340  //Std 802.1D-1998, section 8.3.5)
341  stpUpdateAgeingTime(context, context->forwardDelay);
342 
343  //Start the rapid ageing timer
344  stpStartTimer(&context->rapidAgeingTimer, 0);
345  }
346 
347  //Update the value of the Topology Change flag
348  context->topologyChange = value;
349 }
350 
351 
352 /**
353  * @brief Set port state
354  * @param[in] port Pointer to the bridge port context
355  * @param[in] state Port state (disabled, learning or forwarding)
356  **/
357 
359 {
360  NetInterface *interface;
361  StpBridgeContext *context;
362 
363  //Point to the STP bridge context
364  context = port->context;
365 
366  //Debug message
367  TRACE_INFO("Port %u: Set port state to %s\r\n", port->portIndex,
369 
370  //Learning to Forwarding state transition?
371  if(port->state == STP_PORT_STATE_LEARNING &&
372  state == STP_PORT_STATE_FORWARDING)
373  {
374  //Increment the number of times the port has transitioned from the
375  //Learning state to the Forwarding state
376  port->forwardTransitions++;
377  }
378 
379  //Save the new state of the port
380  port->state = state;
381 
382  //Check STP bridge operation state
383  if(context->running)
384  {
385  //Point to the underlying network interface
386  interface = context->interface;
387 
388  //Valid switch driver?
389  if(interface->switchDriver != NULL &&
390  interface->switchDriver->setPortState != NULL)
391  {
392  SwitchPortState portState;
393 
394  //Translate port state
395  if(state == STP_PORT_STATE_BLOCKING ||
396  state == STP_PORT_STATE_LISTENING)
397  {
398  portState = SWITCH_PORT_STATE_BLOCKING;
399  }
400  else if(state == STP_PORT_STATE_LEARNING)
401  {
402  portState = SWITCH_PORT_STATE_LEARNING;
403  }
404  else if(state == STP_PORT_STATE_FORWARDING)
405  {
406  portState = SWITCH_PORT_STATE_FORWARDING;
407  }
408  else
409  {
410  portState = SWITCH_PORT_STATE_DISABLED;
411  }
412 
413  //Update the state of the specified port
414  interface->switchDriver->setPortState(interface, port->portIndex,
415  portState);
416  }
417  }
418 }
419 
420 
421 /**
422  * @brief Set ageing time for dynamic filtering entries
423  * @param[in] context Pointer to the STP bridge context
424  * @param[in] ageingTime Aging time, in seconds
425  **/
426 
427 void stpUpdateAgeingTime(StpBridgeContext *context, uint32_t ageingTime)
428 {
429  NetInterface *interface;
430 
431  //Debug message
432  TRACE_INFO("Set ageing time to %" PRIu32 " seconds...\r\n", ageingTime);
433 
434  //Check STP bridge operation state
435  if(context->running)
436  {
437  //Point to the underlying network interface
438  interface = context->interface;
439 
440  //Valid switch driver?
441  if(interface->switchDriver != NULL &&
442  interface->switchDriver->setAgingTime != NULL)
443  {
444  //Set ageing time for dynamic filtering entries
445  interface->switchDriver->setAgingTime(interface, ageingTime);
446  }
447  }
448 }
449 
450 
451 /**
452  * @brief Enable reserved multicast table
453  * @param[in] context Pointer to the STP bridge context
454  * @param[in] enable Enable or disable reserved group addresses
455  **/
456 
458 {
459  NetInterface *interface;
460 
461  //Point to the underlying network interface
462  interface = context->interface;
463 
464  //Valid switch driver?
465  if(interface->switchDriver != NULL &&
466  interface->switchDriver->enableRsvdMcastTable != NULL)
467  {
468  //Enable or disable reserved group addresses
469  interface->switchDriver->enableRsvdMcastTable(interface, enable);
470  }
471 }
472 
473 
474 /**
475  * @brief Add a new entry to the static MAC table
476  * @param[in] context Pointer to the STP bridge context
477  * @param[in] macAddr MAC address to be added
478  * @param[in] override This flag specifies whether packets received with a
479  * destination address that matches the MAC address will be forwarded
480  * regardless of the port state
481  * @return Error code
482  **/
483 
485  bool_t override)
486 {
487  error_t error;
488  SwitchFdbEntry entry;
489  NetInterface *interface;
490 
491  //Initialize status code
492  error = NO_ERROR;
493 
494  //Point to the underlying network interface
495  interface = context->interface;
496 
497  //Valid switch driver?
498  if(interface->switchDriver != NULL &&
499  interface->switchDriver->addStaticFdbEntry != NULL)
500  {
501  //Format forwarding database entry
502  entry.macAddr = *macAddr;
503  entry.srcPort = 0;
505  entry.override = override;
506 
507  //Update the static MAC table of the switch
508  error = interface->switchDriver->addStaticFdbEntry(interface, &entry);
509  }
510 
511  //Return status code
512  return error;
513 }
514 
515 
516 /**
517  * @brief Remove an entry from the static MAC table
518  * @param[in] context Pointer to the STP bridge context
519  * @param[in] macAddr MAC address to be removed from the table
520  * @return Error code
521  **/
522 
524  const MacAddr *macAddr)
525 {
526  error_t error;
527  SwitchFdbEntry entry;
528  NetInterface *interface;
529 
530  //Initialize status code
531  error = NO_ERROR;
532 
533  //Point to the underlying network interface
534  interface = context->interface;
535 
536  //Valid switch driver?
537  if(interface->switchDriver != NULL &&
538  interface->switchDriver->deleteStaticFdbEntry != NULL)
539  {
540  //Format forwarding database entry
541  entry.macAddr = *macAddr;
542  entry.srcPort = 0;
543  entry.destPorts = 0;
544  entry.override = FALSE;
545 
546  //Update the static MAC table of the switch
547  error = interface->switchDriver->deleteStaticFdbEntry(interface, &entry);
548  }
549 
550  //Return status code
551  return error;
552 }
553 
554 
555 /**
556  * @brief Configure the permanent database
557  * @param[in] context Pointer to the STP bridge context
558  * @return Error code
559  **/
560 
562 {
563  uint_t i;
564  error_t error;
565 
566  //The Bridge Group Address shall be configured in the permanent database in
567  //order to confine BPDUs to the individual LAN on which they are transmitted
568  //(refer IEEE Std 802.1D-1998, section 7.12.3)
569  error = stpAddStaticFdbEntry(context, &STP_BRIDGE_GROUP_ADDR, TRUE);
570 
571  //Check status code
572  if(!error)
573  {
574  //Add the bridge's address to the static MAC table of the switch
575  error = stpAddStaticFdbEntry(context, &context->bridgeId.addr, FALSE);
576  }
577 
578  //Frames addressed to a bridge port as an end station shall be submitted to
579  //LLC (refer IEEE Std 802.1D-1998, section 7.5)
580  for(i = 0; i < context->numPorts && !error; i++)
581  {
582  //Add the port's address to the static MAC table of the switch
583  error = stpAddStaticFdbEntry(context, &context->ports[i].macAddr, FALSE);
584  }
585 
586  //Check status code
587  if(!error)
588  {
589  //Frames containing any of the reserved addresses in their destination
590  //address field shall not be relayed by the bridge. They shall be
591  //configured in the permanent database (refer IEEE Std 802.1D-1998,
592  //section 7.12.6)
593  stpEnableRsvdMcastTable(context, TRUE);
594  }
595 
596  //Return status code
597  return error;
598 }
599 
600 
601 /**
602  * @brief Unconfigure the permanent database
603  * @param[in] context Pointer to the STP bridge context
604  **/
605 
607 {
608  uint_t i;
609 
610  //Remove the Bridge Group Address from the static MAC table of the switch
612 
613  //Remove the bridge's address from the static MAC table of the switch
614  stpDeleteStaticFdbEntry(context, &context->bridgeId.addr);
615 
616  //Loop through the ports of the bridge
617  for(i = 0; i < context->numPorts; i++)
618  {
619  //Remove the port's address from the static MAC table of the switch
620  stpDeleteStaticFdbEntry(context, &context->ports[i].macAddr);
621  }
622 
623  //Remove reserved group addresses from the permanent database
624  stpEnableRsvdMcastTable(context, FALSE);
625 }
626 
627 
628 /**
629  * @brief Port's MAC address generation
630  * @param[in] port Pointer to the bridge port context
631  **/
632 
634 {
635  int_t i;
636  uint8_t c;
637  MacAddr *bridgeAddr;
638 
639  //Get bridge's MAC address
640  bridgeAddr = &port->context->bridgeId.addr;
641 
642  //Retrieve port index
643  c = port->portIndex;
644 
645  //Generate a unique MAC address for the port
646  for(i = 5; i >= 0; i--)
647  {
648  //Generate current byte
649  port->macAddr.b[i] = bridgeAddr->b[i] + c;
650 
651  //Propagate the carry if necessary
652  if(port->macAddr.b[i] < bridgeAddr->b[i])
653  {
654  c = 1;
655  }
656  else
657  {
658  c = 0;
659  }
660  }
661 }
662 
663 
664 /**
665  * @brief Check bridge parameters
666  * @param[in] maxAge Value of the Bridge Max Age parameter
667  * @param[in] helloTime Value of the Bridge Hello Time parameter
668  * @param[in] forwardDelay Value of the Bridge Forward Delay parameter
669  * @return TRUE if the set of parameters is valid, else FALSE
670  **/
671 
674 {
675  bool_t valid;
676 
677  //A bridge shall enforce the following relationships (refer to IEEE Std
678  //802.1D-1998, section 8.10.2)
679  if(maxAge >= (2 * (helloTime + 1)) && maxAge <= (2 * (forwardDelay - 1)))
680  {
681  valid = TRUE;
682  }
683  else
684  {
685  valid = FALSE;
686  }
687 
688  //Return TRUE if the set of parameters is valid, else FALSE
689  return valid;
690 }
691 
692 
693 /**
694  * @brief Convert a parameter to string representation
695  * @param[in] value Parameter value
696  * @param[in] paramList List of acceptable parameters
697  * @param[in] paramListLen Number of entries in the list
698  * @return NULL-terminated string describing the parameter
699  **/
700 
701 const char_t *stpGetParamName(uint_t value, const StpParamName *paramList,
702  size_t paramListLen)
703 {
704  uint_t i;
705 
706  //Default name for unknown values
707  static const char_t defaultName[] = "Unknown";
708 
709  //Loop through the list of acceptable parameters
710  for(i = 0; i < paramListLen; i++)
711  {
712  if(paramList[i].value == value)
713  {
714  return paramList[i].name;
715  }
716  }
717 
718  //Unknown value
719  return defaultName;
720 }
721 
722 
723 /**
724  * @brief Start timer
725  * @param[in] timer Pointer the timer to start (or restart)
726  * @param[in] value Initial value of the timer
727  **/
728 
730 {
731  //Set the initial value of the timer
732  timer->value = value;
733  //Start the timer
734  timer->active = TRUE;
735 }
736 
737 
738 /**
739  * @brief Stop timer
740  * @param[in] timer Pointer the timer to stop
741  **/
742 
743 void stpStopTimer(StpTimer *timer)
744 {
745  //Stop the timer
746  timer->active = FALSE;
747 }
748 
749 
750 /**
751  * @brief Increment the timer and check for expiration
752  * @param[in] timer Pointer the timer to increment
753  * @param[in] timeout Timeout value
754  * @return TRUE if the timer has expired, else FALSE
755  **/
756 
758 {
759  bool_t flag;
760 
761  //Initialize flag
762  flag = FALSE;
763 
764  //Check whether the timer is active
765  if(timer->active)
766  {
767  //Increment the timer and check for expiration
768  if(++timer->value >= timeout)
769  {
770  //The timer has expired
771  flag = TRUE;
772  //Stop the timer
773  timer->active = FALSE;
774  }
775  }
776 
777  //Return TRUE if the timer has expired
778  return flag;
779 }
780 
781 #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
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 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
#define SWITCH_CPU_PORT_MASK
Definition: nic.h:60
SwitchPortState
Switch port state.
Definition: nic.h:134
@ SWITCH_PORT_STATE_FORWARDING
Definition: nic.h:140
@ SWITCH_PORT_STATE_BLOCKING
Definition: nic.h:137
@ SWITCH_PORT_STATE_DISABLED
Definition: nic.h:136
@ SWITCH_PORT_STATE_LEARNING
Definition: nic.h:139
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define arraysize(a)
Definition: os_port.h:71
#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[]
uint16_t forwardDelay
Definition: rstp_bpdu.h:109
uint16_t helloTime
Definition: rstp_bpdu.h:108
uint16_t maxAge
Definition: rstp_bpdu.h:107
STP (Spanning Tree Protocol)
#define StpBridgeContext
Definition: stp.h:36
#define StpBridgePort
Definition: stp.h:40
const MacAddr STP_BRIDGE_GROUP_ADDR
Definition: stp_bpdu.c:45
#define STP_PORT_NUM_MASK
Definition: stp_bpdu.h:43
StpBridgeId
Definition: stp_common.h:148
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_FORWARDING
Definition: stp_common.h:114
@ STP_PORT_STATE_DISABLED
Definition: stp_common.h:109
error_t stpDeleteStaticFdbEntry(StpBridgeContext *context, const MacAddr *macAddr)
Remove an entry from the static MAC table.
Definition: stp_misc.c:523
error_t stpConfigurePermanentDatabase(StpBridgeContext *context)
Configure the permanent database.
Definition: stp_misc.c:561
void stpUpdateTopologyChange(StpBridgeContext *context, bool_t value)
Set the Topology Change flag.
Definition: stp_misc.c:325
bool_t stpIncrementTimer(StpTimer *timer, uint_t timeout)
Increment the timer and check for expiration.
Definition: stp_misc.c:757
void stpUpdateAgeingTime(StpBridgeContext *context, uint32_t ageingTime)
Set ageing time for dynamic filtering entries.
Definition: stp_misc.c:427
void stpUnlock(StpBridgeContext *context)
Release exclusive access to the STP bridge context.
Definition: stp_misc.c:71
int_t stpComparePortNum(uint16_t portId1, uint16_t portId2)
Compare port numbers.
Definition: stp_misc.c:244
void stpGeneratePortAddr(StpBridgePort *port)
Port's MAC address generation.
Definition: stp_misc.c:633
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
int_t stpCompareBridgeAddr(const MacAddr *addr1, const MacAddr *addr2)
Compare bridge addresses.
Definition: stp_misc.c:281
StpBridgePort * stpGetBridgePort(StpBridgeContext *context, uint16_t portId)
Retrieve the port that matches the specified port number.
Definition: stp_misc.c:212
const char_t * stpGetParamName(uint_t value, const StpParamName *paramList, size_t paramListLen)
Convert a parameter to string representation.
Definition: stp_misc.c:701
void stpUnconfigurePermanentDatabase(StpBridgeContext *context)
Unconfigure the permanent database.
Definition: stp_misc.c:606
void stpTick(StpBridgeContext *context)
STP tick handler.
Definition: stp_misc.c:86
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
error_t stpAddStaticFdbEntry(StpBridgeContext *context, const MacAddr *macAddr, bool_t override)
Add a new entry to the static MAC table.
Definition: stp_misc.c:484
void stpLock(StpBridgeContext *context)
Acquire exclusive access to the STP bridge context.
Definition: stp_misc.c:59
const StpParamName stpPortStates[]
Definition: stp_misc.c:44
void stpEnableRsvdMcastTable(StpBridgeContext *context, bool_t enable)
Enable reserved multicast table.
Definition: stp_misc.c:457
STP helper functions.
void stpMessageAgeTimerExpiry(StpBridgePort *port)
Message Age Timer expiry (8.7.4)
void stpTcnTimerExpiry(StpBridgeContext *context)
Topology Change Notification Timer expiry (8.7.6)
void stpHelloTimerExpiry(StpBridgeContext *context)
Hello Timer expiry (8.7.3)
void stpTopologyChangeTimerExpiry(StpBridgeContext *context)
Topology Change Timer expiry (8.7.7)
void stpForwardDelayTimerExpiry(StpBridgePort *port)
Forward Delay Timer expiry (8.7.5)
void stpHoldTimerExpiry(StpBridgePort *port)
Hold Timer expiry (8.7.8)
Operation of the protocol.
Parameter value/name binding.
Definition: stp_misc.h:48
const char_t * name
Definition: stp_misc.h:50
STP timer.
Definition: stp.h:204
bool_t active
Definition: stp.h:205
uint_t value
Definition: stp.h:206
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