rstp_bpdu.c
Go to the documentation of this file.
1 /**
2  * @file rstp_bpdu.c
3  * @brief BPDU processing
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSTP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL RSTP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "rstp/rstp.h"
36 #include "rstp/rstp_fsm.h"
37 #include "rstp/rstp_bpdu.h"
38 #include "rstp/rstp_conditions.h"
39 #include "rstp/rstp_misc.h"
40 #include "debug.h"
41 
42 //Check TCP/IP stack configuration
43 #if (RSTP_SUPPORT == ENABLED)
44 
45 //Bridge group address (refer to IEEE Std 802.1D-2004, section 7.12.3)
46 const MacAddr RSTP_BRIDGE_GROUP_ADDR = {{{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}}};
47 
48 //Protocol versions
50 {
51  {STP_PROTOCOL_VERSION, "STP"},
52  {RSTP_PROTOCOL_VERSION, "RSTP"}
53 };
54 
55 //BPDU types
57 {
58  {RSTP_BPDU_TYPE_CONFIG, "CONFIG"},
59  {RSTP_BPDU_TYPE_TCN, "TCN"},
60  {RSTP_BPDU_TYPE_RST, "RST"}
61 };
62 
63 
64 /**
65  * @brief Process incoming LLC frame
66  * @param[in] interface Underlying network interface
67  * @param[in] ethHeader Pointer to the Ethernet header
68  * @param[in] data Pointer to the LLC frame
69  * @param[in] length Length of the LLC frame, in bytes
70  * @param[in] ancillary Additional options passed to the stack along with
71  * the packet
72  * @param[in] param Pointer to the RSTP bridge context
73  **/
74 
75 void rstpProcessLlcFrame(NetInterface *interface, EthHeader *ethHeader,
76  const uint8_t *data, size_t length, NetRxAncillary *ancillary, void *param)
77 {
78  const LlcHeader *llcHeader;
79  const RstpBpdu *bpdu;
80  RstpBridgeContext *context;
82 
83  //Point to the RSTP bridge context
84  context = (RstpBridgeContext *) param;
85 
86  //The Bridge Group Address shall be used in the destination address field
87  //of all MAC frames conveying BPDUs (refer to IEEE Std 802.1D-2004, section
88  //7.12.3)
89  if(!macCompAddr(&ethHeader->destAddr, &RSTP_BRIDGE_GROUP_ADDR))
90  return;
91 
92  //Check the length of the LLC frame
93  if(length < sizeof(LlcHeader))
94  return;
95 
96  //Point to the LLC header
97  llcHeader = (LlcHeader *) data;
98 
99  //The DSAP and SSAP fields must use the standard LLC address assigned to
100  //the Bridge Spanning Tree Protocol (refer to IEEE Std 802.1D-2004, section
101  //7.12.3)
102  if(llcHeader->dsap != STP_LLC_DSAP || llcHeader->ssap != STP_LLC_SSAP ||
103  llcHeader->control != STP_LLC_CTRL)
104  {
105  return;
106  }
107 
108  //Invalid port number?
109  if(ancillary->port < 1 || ancillary->port > context->numPorts)
110  return;
111 
112  //Retrieve the port that matches the specified port number
113  port = &context->ports[ancillary->port - 1];
114 
115  //BPDUs are encapsulated using 802.2 LLC header
116  bpdu = (RstpBpdu *) (data + sizeof(LlcHeader));
117 
118  //Retrieve the length of the BPDU
119  length -= sizeof(LlcHeader);
120 
121  //Process incoming BPDU
122  rstpProcessBpdu(port, bpdu, length);
123 }
124 
125 
126 /**
127  * @brief Process incoming bridge protocol data unit
128  * @param[in] port Pointer to the bridge port context
129  * @param[in] bpdu Pointer to the received BPDU
130  * @param[in] length Length of the BPDU, in bytes
131  * @return Error code
132  **/
133 
135  size_t length)
136 {
137  error_t error;
138  uint8_t bpduType;
139  RstpBridgeContext *context;
140 
141  //Debug message
142  TRACE_INFO("Port %" PRIu8 ": BPDU received (%" PRIuSIZE " bytes)...\r\n",
143  port->portIndex, length);
144 
145  //Dump BPDU for debugging purpose
146  rstpDumpBpdu(bpdu, length);
147 
148  //Point to the RSTP bridge context
149  context = port->context;
150 
151  //The BPDU must contain at least four octets
153  return ERROR_INVALID_LENGTH;
154 
155  //The Protocol Identifier must have the value specified for BPDUs
156  if(ntohs(bpdu->protocolId) != STP_PROTOCOL_ID)
157  return ERROR_INVALID_LENGTH;
158 
159  //The type of the BPDU is encoded as a single octet
160  bpduType = bpdu->bpduType;
161 
162  //Check BPDU type
164  {
165  //Validate the received Configuration BPDU according to 9.3.4 rules
166  error = rstpValidateConfigBpdu(port, bpdu, length);
167  //Invalid Configuration BPDU?
168  if(error)
169  return error;
170 
171  //All octets that appear in the BPDU beyond the largest numbered octet
172  //defined for a given BPDU type shall be ignored
174  }
175  else if(bpduType == RSTP_BPDU_TYPE_TCN)
176  {
177  //All octets that appear in the BPDU beyond the largest numbered octet
178  //defined for a given BPDU type shall be ignored
180  }
181  else if(bpduType == RSTP_BPDU_TYPE_RST)
182  {
183  //RST BPDUs are not recognized by STP bridges (refer IEEE Std 802.1D-2004,
184  //section 17.4)
185  if(stpVersion(context))
186  return ERROR_INVALID_VERSION;
187 
188  //A Rapid Spanning Tree BPDU must contain at least 36 octets
190  return ERROR_INVALID_LENGTH;
191 
192  //All octets that appear in the BPDU beyond the largest numbered octet
193  //defined for a given BPDU type shall be ignored
195 
196  //Unknown port role?
197  if((bpdu->flags & RSTP_BPDU_FLAG_PORT_ROLE) ==
199  {
200  //If the Unknown value of the Port Role parameter is received, the
201  //state machine will effectively treat the RST BPDU as if it were a
202  //Configuration BPDU (refer to IEEE Std 802.1D-2004, section 9.2.9)
204 
205  //Validate the received Configuration BPDU according to 9.3.4 rules
206  error = rstpValidateConfigBpdu(port, bpdu, length);
207  //Invalid Configuration BPDU?
208  if(error)
209  return error;
210 
211  //All octets that appear in the BPDU beyond the largest numbered octet
212  //defined for a given BPDU type shall be ignored
214  }
215  }
216  else
217  {
218  //Invalid BPDU received
219  return ERROR_INVALID_TYPE;
220  }
221 
222  //The received BPDU is valid
223  osMemcpy(&context->bpdu, bpdu, length);
224 
225  //Fix the BPDU type
226  context->bpdu.bpduType = bpduType;
227 
228  //All flags that are undefined for a given BPDU type shall be ignored (refer
229  //to IEEE Std 802.1D-2004, section 9.3.4)
231  {
232  //The Topology Change Acknowledgment flag is encoded in bit 8. The
233  //Topology Change flag is encoded in bit 1. The remaining flags, bits 2
234  //through 7, are unused and take the value 0
235  context->bpdu.flags &= RSTP_BPDU_FLAG_TC_ACK | RSTP_BPDU_FLAG_TC;
236  }
237  else if(bpduType == RSTP_BPDU_TYPE_RST)
238  {
239  //The Topology Change Acknowledgment flag is encoded in bit 8 as zero
240  context->bpdu.flags &= ~RSTP_BPDU_FLAG_TC_ACK;
241  }
242  else
243  {
244  //A Topology Change Notification BPDU does not contain any flags
245  context->bpdu.flags = 0;
246  }
247 
248  //The rcvdBPDU variable notifies the Port Receive state machine when a valid
249  //Configuration, TCN, or RST BPDU is received on the port
250  port->rcvdBpdu = TRUE;
251 
252  //Process incoming BPDU
253  rstpFsm(context);
254 
255  //Clear BPDU
256  osMemset(&context->bpdu, 0, sizeof(RstpBpdu));
257 
258  //Successful processing
259  return NO_ERROR;
260 }
261 
262 
263 /**
264  * @brief Validate Configuration BPDU
265  * @param[in] port Pointer to the bridge port context
266  * @param[in] bpdu Pointer to the received Configuration BPDU
267  * @param[in] length Length of the Configuration BPDU, in bytes
268  * @return Error code
269  **/
270 
272  size_t length)
273 {
274  RstpBridgeContext *context;
275 
276  //Point to the RSTP bridge context
277  context = port->context;
278 
279  //A Configuration BPDU must contain at least 35 octets
281  return ERROR_INVALID_LENGTH;
282 
283  //The BPDU's Message Age must be less than its Max Age parameter
284  if(ntohs(bpdu->messageAge) >= ntohs(bpdu->maxAge))
285  return ERROR_INVALID_PACKET;
286 
287  //The Bridge Identifier and Port Identifier parameters from the received BPDU
288  //must not match the values that would be transmitted in a BPDU from this port
289  if(rstpCompareBridgeAddr(&bpdu->bridgeId.addr, &context->bridgeId.addr) == 0 &&
290  rstpComparePortNum(ntohs(bpdu->portId), port->portId) == 0)
291  {
292  return ERROR_WRONG_IDENTIFIER;
293  }
294 
295  //The received Configuration BPDU is valid
296  return NO_ERROR;
297 }
298 
299 
300 /**
301  * @brief Send bridge protocol data unit
302  * @param[in] port Pointer to the bridge port context
303  * @param[in] bpdu Pointer to the BPDU to be transmitted
304  * @param[in] length Length of the BPDU, in bytes
305  * @return Error code
306  **/
307 
309  size_t length)
310 {
311  error_t error;
312  size_t offset;
313  LlcHeader *llcHeader;
314  NetBuffer *buffer;
315  NetTxAncillary ancillary;
316  RstpBridgeContext *context;
317 
318  //Debug message
319  TRACE_INFO("Port %" PRIu8 ": Sending BPDU (%" PRIuSIZE " bytes)...\r\n",
320  port->portIndex, length);
321 
322  //Dump BPDU for debugging purpose
323  rstpDumpBpdu(bpdu, length);
324 
325  //Point to the RSTP bridge context
326  context = port->context;
327 
328  //Allocate a buffer to hold the 802.2 LLC header
329  buffer = ethAllocBuffer(sizeof(LlcHeader), &offset);
330 
331  //Successful memory allocation?
332  if(buffer != NULL)
333  {
334  //Point to the LLC header
335  llcHeader = netBufferAt(buffer, offset, 0);
336 
337  //The DSAP and SSAP fields must use the standard LLC address assigned
338  //to the Bridge Spanning Tree Protocol (refer to IEEE Std 802.1D-2004,
339  //section 7.12.3)
340  llcHeader->dsap = STP_LLC_DSAP;
341  llcHeader->ssap = STP_LLC_SSAP;
342  llcHeader->control = STP_LLC_CTRL;
343 
344  //BPDUs are encapsulated using 802.2 LLC header
345  error = netBufferAppend(buffer, bpdu, length);
346 
347  //Check status code
348  if(!error)
349  {
350  //Calculate the length of the LLC frame
351  length += sizeof(LlcHeader);
352 
353  //Additional options can be passed to the stack along with the packet
354  ancillary = NET_DEFAULT_TX_ANCILLARY;
355  //Specify the source MAC address
356  ancillary.srcMacAddr = port->macAddr;
357  //Specify the destination port
358  ancillary.port = port->portIndex;
359  //BPDUs are transmitted regardless of the port state
360  ancillary.override = TRUE;
361 
362  //The Bridge Group Address is used as destination MAC address to carry
363  //BPDUs between STP entities
364  error = ethSendFrame(context->interface, &RSTP_BRIDGE_GROUP_ADDR,
365  length, buffer, offset, &ancillary);
366  }
367 
368  //Free previously allocated memory
369  netBufferFree(buffer);
370  }
371  else
372  {
373  //Failed to allocate memory
374  error = ERROR_OUT_OF_MEMORY;
375  }
376 
377  //Return status code
378  return error;
379 }
380 
381 
382 /**
383  * @brief Dump BPDU for debugging purpose
384  * @param[in] bpdu Pointer to the BPDU to dump
385  * @param[in] length Length of the BPDU, in bytes
386  * @return Error code
387  **/
388 
389 error_t rstpDumpBpdu(const RstpBpdu *bpdu, size_t length)
390 {
391 #if (RSTP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
392  uint32_t t;
393 
394  //The BPDU must contain at least four octets
396  return ERROR_INVALID_LENGTH;
397 
398  //Dump Protocol Identifier
399  TRACE_DEBUG(" Protocol Identifier = %" PRIu16 "\r\n",
400  ntohs(bpdu->protocolId));
401 
402  //Dump Protocol Version Identifier
403  TRACE_DEBUG(" Protocol Version Identifier = %" PRIu8 " (%s)\r\n",
404  bpdu->protocolVersionId, rstpGetParamName(bpdu->protocolVersionId,
406 
407  //Dump BPDU Type
408  TRACE_DEBUG(" BPDU Type = 0x%02" PRIX8 " (%s)\r\n", bpdu->bpduType,
410 
411  //Check the length of the BPDU
413  {
414  //Dump Flags
415  rstpDumpFlags(bpdu->flags);
416 
417  //Dump Root Identifier
418  TRACE_DEBUG(" Root Identifier = %" PRIu16 " / %s\r\n",
419  ntohs(bpdu->rootId.priority), macAddrToString(&bpdu->rootId.addr, NULL));
420 
421  //Dump Root Path Cost
422  TRACE_DEBUG(" Root Path Cost = %" PRIu32 "\r\n", ntohl(bpdu->rootPathCost));
423 
424  //Dump Bridge Identifier
425  TRACE_DEBUG(" Bridge Identifier = %" PRIu16 " / %s\r\n",
426  ntohs(bpdu->bridgeId.priority), macAddrToString(&bpdu->bridgeId.addr, NULL));
427 
428  //Dump Port Identifier
429  TRACE_DEBUG(" Port Identifier = 0x%04" PRIX16 "\r\n", ntohs(bpdu->portId));
430 
431  //Dump Message Age
432  t = ntohs(bpdu->messageAge) * 1000 / 256;
433  TRACE_DEBUG(" Message Age = %" PRIu32 ".%03" PRIu32 "\r\n", t / 1000, t % 1000);
434 
435  //Dump Max Age
436  t = ntohs(bpdu->maxAge) * 1000 / 256;
437  TRACE_DEBUG(" Max Age = %" PRIu32 ".%03" PRIu32 "\r\n", t / 1000, t % 1000);
438 
439  //Dump Hello Time
440  t = ntohs(bpdu->helloTime) * 1000 / 256;
441  TRACE_DEBUG(" Hello Time = %" PRIu32 ".%03" PRIu32 "\r\n", t / 1000, t % 1000);
442 
443  //Dump Forward Delay
444  t = ntohs(bpdu->forwardDelay) * 1000 / 256;
445  TRACE_DEBUG(" Forward Delay = %" PRIu32 ".%03" PRIu32 "\r\n", t / 1000, t % 1000);
446  }
447 
448  //Check the length of the BPDU
450  {
451  //Dump Version 1 Length
452  TRACE_DEBUG(" Version 1 Length = %" PRIu8 "\r\n", bpdu->version1Length);
453  }
454 #endif
455 
456  //Successful processing
457  return NO_ERROR;
458 }
459 
460 
461 /**
462  * @brief Dump Flags field for debugging purpose
463  * @param[in] flags Value of the Flags field
464  **/
465 
466 void rstpDumpFlags(uint8_t flags)
467 {
468  uint8_t role;
469 
470  //Dump Flags field
471  TRACE_DEBUG(" Flags = 0x%02" PRIX8, flags);
472 
473  //Check whether any flag is set
474  if(flags != 0)
475  {
476  //Debug message
477  TRACE_DEBUG(" (");
478 
479  //Decode flags
480  while(flags != 0)
481  {
482  if((flags & RSTP_BPDU_FLAG_TC_ACK) != 0)
483  {
484  //The Topology Change Acknowledgment flag is set
485  TRACE_DEBUG("TcAck");
486  //Clear flag
488  }
489  else if((flags & RSTP_BPDU_FLAG_AGREEMENT) != 0)
490  {
491  //The Agreement flag is set
492  TRACE_DEBUG("Agreement");
493  //Clear flag
495  }
496  else if((flags & RSTP_BPDU_FLAG_FORWARDING) != 0)
497  {
498  //The Forwarding flag is set
499  TRACE_DEBUG("Forwarding");
500  //Clear flag
502  }
503  else if((flags & RSTP_BPDU_FLAG_LEARNING) != 0)
504  {
505  //The Learning flag is set
506  TRACE_DEBUG("Learning");
507  //Clear flag
509  }
510  else if((flags & RSTP_BPDU_FLAG_PORT_ROLE) != 0)
511  {
512  //Decode port role
514 
515  //Check port role
517  {
518  TRACE_DEBUG("AltBackupRole");
519  }
520  else if(role == RSTP_BPDU_FLAG_PORT_ROLE_ROOT)
521  {
522  TRACE_DEBUG("RootRole");
523  }
524  else if(role == RSTP_BPDU_FLAG_PORT_ROLE_DESIGNATED)
525  {
526  TRACE_DEBUG("DesignatedRole");
527  }
528 
529  //Clear flag
531  }
532  else if((flags & RSTP_BPDU_FLAG_PROPOSAL) != 0)
533  {
534  //The Proposal flag is set
535  TRACE_DEBUG("Proposal");
536  //Clear flag
538  }
539  else if((flags & RSTP_BPDU_FLAG_TC) != 0)
540  {
541  //The Topology Change flag is set
542  TRACE_DEBUG("Tc");
543  //Clear flag
545  }
546 
547  //Any other flag set?
548  if(flags != 0)
549  {
550  TRACE_DEBUG(", ");
551  }
552  }
553 
554  //Debug message
555  TRACE_DEBUG(")");
556  }
557 
558  //Terminate with a line feed
559  TRACE_DEBUG("\r\n");
560 }
561 
562 #endif
#define RSTP_RST_BPDU_SIZE
Definition: rstp_bpdu.h:40
error_t rstpProcessBpdu(RstpBridgePort *port, const RstpBpdu *bpdu, size_t length)
Process incoming bridge protocol data unit.
Definition: rstp_bpdu.c:134
#define RSTP_TCN_BPDU_SIZE
Definition: rstp_bpdu.h:38
@ RSTP_BPDU_FLAG_FORWARDING
Definition: rstp_bpdu.h:78
const NetTxAncillary NET_DEFAULT_TX_ANCILLARY
Definition: net_misc.c:71
#define STP_LLC_CTRL
Definition: stp_common.h:85
RSTP state machine conditions.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
uint8_t t
Definition: lldp_ext_med.h:212
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:222
error_t ethSendFrame(NetInterface *interface, const MacAddr *destAddr, uint16_t type, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send an Ethernet frame.
Definition: ethernet.c:399
@ RSTP_BPDU_TYPE_CONFIG
Definition: rstp_bpdu.h:58
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
int_t rstpCompareBridgeAddr(const MacAddr *addr1, const MacAddr *addr2)
Compare bridge addresses.
Definition: rstp_misc.c:256
RSTP helper functions.
uint8_t bpduType
Definition: rstp_bpdu.h:100
EthHeader
Definition: ethernet.h:223
@ ERROR_INVALID_VERSION
Definition: error.h:118
error_t rstpSendBpdu(RstpBridgePort *port, const RstpBpdu *bpdu, size_t length)
Send bridge protocol data unit.
Definition: rstp_bpdu.c:308
#define RSTP_CONFIG_BPDU_SIZE
Definition: rstp_bpdu.h:39
#define RstpBridgeContext
Definition: rstp.h:36
#define STP_LLC_DSAP
Definition: stp_common.h:83
@ STP_PROTOCOL_VERSION
STP version.
Definition: stp_common.h:97
#define STP_PROTOCOL_ID
Definition: stp_common.h:80
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
#define STP_MIN_BPDU_SIZE
Definition: stp_common.h:88
RSTP (Rapid Spanning Tree Protocol)
char_t * macAddrToString(const MacAddr *macAddr, char_t *str)
Convert a MAC address to a dash delimited string.
Definition: ethernet.c:919
#define NetRxAncillary
Definition: net_misc.h:40
@ RSTP_BPDU_FLAG_PORT_ROLE_DESIGNATED
Definition: rstp_bpdu.h:76
@ ERROR_INVALID_PACKET
Definition: error.h:140
#define NetInterface
Definition: net.h:36
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ RSTP_BPDU_FLAG_TC
Definition: rstp_bpdu.h:70
#define NetTxAncillary
Definition: net_misc.h:36
void rstpDumpFlags(uint8_t flags)
Dump Flags field for debugging purpose.
Definition: rstp_bpdu.c:466
@ RSTP_BPDU_FLAG_AGREEMENT
Definition: rstp_bpdu.h:79
@ ERROR_INVALID_TYPE
Definition: error.h:115
#define TRACE_INFO(...)
Definition: debug.h:95
const MacAddr RSTP_BRIDGE_GROUP_ADDR
Definition: rstp_bpdu.c:46
uint8_t length
Definition: tcp.h:368
@ RSTP_BPDU_FLAG_PORT_ROLE_ALT_BACKUP
Definition: rstp_bpdu.h:74
const RstpParamName rstpBpduTypes[]
Definition: rstp_bpdu.c:56
MacAddr
Definition: ethernet.h:195
RstpBpdu
Definition: rstp_bpdu.h:111
LlcHeader
Definition: ethernet.h:235
@ RSTP_BPDU_TYPE_RST
Definition: rstp_bpdu.h:60
uint16_t port
Definition: dns_common.h:267
#define ntohs(value)
Definition: cpu_endian.h:421
@ RSTP_BPDU_FLAG_TC_ACK
Definition: rstp_bpdu.h:80
uint8_t flags
Definition: tcp.h:351
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define STP_LLC_SSAP
Definition: stp_common.h:84
int_t rstpComparePortNum(uint16_t portId1, uint16_t portId2)
Compare port numbers.
Definition: rstp_misc.c:219
bool_t stpVersion(RstpBridgeContext *context)
stpVersion condition (17.20.12)
@ RSTP_BPDU_FLAG_LEARNING
Definition: rstp_bpdu.h:77
error_t netBufferAppend(NetBuffer *dest, const void *src, size_t length)
Append data a multi-part buffer.
Definition: net_mem.c:604
@ RSTP_BPDU_FLAG_PORT_ROLE_ROOT
Definition: rstp_bpdu.h:75
error_t rstpValidateConfigBpdu(RstpBridgePort *port, const RstpBpdu *bpdu, size_t length)
Validate Configuration BPDU.
Definition: rstp_bpdu.c:271
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:130
error_t rstpDumpBpdu(const RstpBpdu *bpdu, size_t length)
Dump BPDU for debugging purpose.
Definition: rstp_bpdu.c:389
void rstpProcessLlcFrame(NetInterface *interface, EthHeader *ethHeader, const uint8_t *data, size_t length, NetRxAncillary *ancillary, void *param)
Process incoming LLC frame.
Definition: rstp_bpdu.c:75
@ RSTP_BPDU_FLAG_PORT_ROLE_UNKNOWN
Definition: rstp_bpdu.h:73
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
Parameter value/name binding.
Definition: rstp_misc.h:48
@ RSTP_BPDU_TYPE_TCN
Definition: rstp_bpdu.h:59
@ RSTP_PROTOCOL_VERSION
RSTP version.
Definition: stp_common.h:98
void * netBufferAt(const NetBuffer *buffer, size_t offset, size_t length)
Returns a pointer to a data segment.
Definition: net_mem.c:418
@ RSTP_BPDU_FLAG_PROPOSAL
Definition: rstp_bpdu.h:71
NetBuffer * ethAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an Ethernet frame.
Definition: ethernet.c:777
#define PRIuSIZE
#define osMemset(p, value, length)
Definition: os_port.h:135
BPDU processing.
void rstpFsm(RstpBridgeContext *context)
RSTP state machine implementation.
Definition: rstp_fsm.c:152
#define ntohl(value)
Definition: cpu_endian.h:422
const char_t * rstpGetParamName(uint_t value, const RstpParamName *paramList, size_t paramListLen)
Convert a parameter to string representation.
Definition: rstp_misc.c:883
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ RSTP_BPDU_FLAG_PORT_ROLE
Definition: rstp_bpdu.h:72
#define RstpBridgePort
Definition: rstp.h:40
#define arraysize(a)
Definition: os_port.h:71
Rapid Spanning Tree state machines.
const RstpParamName rstpProtocolVersions[]
Definition: rstp_bpdu.c:49