lib/rstp: More robust thread safety.
[cascardo/ovs.git] / lib / rstp-common.h
1 /*
2  * Copyright (c) 2011-2014 M3S, Srl - Italy
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * Rapid Spanning Tree Protocol (IEEE 802.1D-2004) common header file.
19  *
20  * Authors:
21  *         Martino Fornasa <mf@fornasa.it>
22  *         Daniele Venturino <daniele.venturino@m3s.it>
23  *
24  * References to IEEE 802.1D-2004 standard are enclosed in square brackets.
25  * E.g. [17.3], [Table 17-1], etc.
26  *
27  */
28
29 #ifndef RSTP_COMMON_H
30 #define RSTP_COMMON_H 1
31
32 #include "rstp.h"
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include "list.h"
36 #include "ovs-atomic.h"
37 #include "packets.h"
38
39 enum admin_port_state {
40     RSTP_ADMIN_BRIDGE_PORT_STATE_DISABLED = 0,
41     RSTP_ADMIN_BRIDGE_PORT_STATE_ENABLED = 1
42 };
43
44 enum oper_p2p_mac_state {
45     RSTP_OPER_P2P_MAC_STATE_DISABLED = 0,
46     RSTP_OPER_P2P_MAC_STATE_ENABLED = 1
47 };
48
49 /* State enumerations for state machines defined in rstp-state-machines.c */
50 enum port_receive_state_machine {
51     PORT_RECEIVE_SM_INIT,
52     PORT_RECEIVE_SM_DISCARD_EXEC,
53     PORT_RECEIVE_SM_DISCARD,
54     PORT_RECEIVE_SM_RECEIVE_EXEC,
55     PORT_RECEIVE_SM_RECEIVE
56 };
57 enum port_transmit_state_machine {
58     PORT_TRANSMIT_SM_INIT,
59     PORT_TRANSMIT_SM_TRANSMIT_INIT_EXEC,
60     PORT_TRANSMIT_SM_TRANSMIT_INIT,
61     PORT_TRANSMIT_SM_TRANSMIT_PERIODIC_EXEC,
62     PORT_TRANSMIT_SM_TRANSMIT_PERIODIC,
63     PORT_TRANSMIT_SM_IDLE_EXEC,
64     PORT_TRANSMIT_SM_IDLE,
65     PORT_TRANSMIT_SM_TRANSMIT_CONFIG_EXEC,
66     PORT_TRANSMIT_SM_TRANSMIT_CONFIG,
67     PORT_TRANSMIT_SM_TRANSMIT_TCN_EXEC,
68     PORT_TRANSMIT_SM_TRANSMIT_TCN,
69     PORT_TRANSMIT_SM_TRANSMIT_RSTP_EXEC,
70     PORT_TRANSMIT_SM_TRANSMIT_RSTP
71 };
72 enum bridge_detection_state_machine {
73     BRIDGE_DETECTION_SM_INIT,
74     BRIDGE_DETECTION_SM_EDGE_EXEC,
75     BRIDGE_DETECTION_SM_EDGE,
76     BRIDGE_DETECTION_SM_NOT_EDGE_EXEC,
77     BRIDGE_DETECTION_SM_NOT_EDGE
78 };
79 enum port_protocol_migration_state_machine {
80     PORT_PROTOCOL_MIGRATION_SM_INIT,
81     PORT_PROTOCOL_MIGRATION_SM_CHECKING_RSTP_EXEC,
82     PORT_PROTOCOL_MIGRATION_SM_CHECKING_RSTP,
83     PORT_PROTOCOL_MIGRATION_SM_SELECTING_STP_EXEC,
84     PORT_PROTOCOL_MIGRATION_SM_SELECTING_STP,
85     PORT_PROTOCOL_MIGRATION_SM_SENSING_EXEC,
86     PORT_PROTOCOL_MIGRATION_SM_SENSING
87 };
88 enum port_information_state_machine {
89     PORT_INFORMATION_SM_INIT,
90     PORT_INFORMATION_SM_DISABLED_EXEC,
91     PORT_INFORMATION_SM_DISABLED,
92     PORT_INFORMATION_SM_AGED_EXEC,
93     PORT_INFORMATION_SM_AGED,
94     PORT_INFORMATION_SM_UPDATE_EXEC,
95     PORT_INFORMATION_SM_UPDATE,
96     PORT_INFORMATION_SM_CURRENT_EXEC,
97     PORT_INFORMATION_SM_CURRENT,
98     PORT_INFORMATION_SM_RECEIVE_EXEC,
99     PORT_INFORMATION_SM_RECEIVE,
100     PORT_INFORMATION_SM_OTHER_EXEC,
101     PORT_INFORMATION_SM_OTHER,
102     PORT_INFORMATION_SM_NOT_DESIGNATED_EXEC,
103     PORT_INFORMATION_SM_NOT_DESIGNATED,
104     PORT_INFORMATION_SM_INFERIOR_DESIGNATED_EXEC,
105     PORT_INFORMATION_SM_INFERIOR_DESIGNATED,
106     PORT_INFORMATION_SM_REPEATED_DESIGNATED_EXEC,
107     PORT_INFORMATION_SM_REPEATED_DESIGNATED,
108     PORT_INFORMATION_SM_SUPERIOR_DESIGNATED_EXEC,
109     PORT_INFORMATION_SM_SUPERIOR_DESIGNATED
110 };
111 enum port_role_selection_state_machine {
112     PORT_ROLE_SELECTION_SM_INIT,
113     PORT_ROLE_SELECTION_SM_INIT_BRIDGE_EXEC,
114     PORT_ROLE_SELECTION_SM_INIT_BRIDGE,
115     PORT_ROLE_SELECTION_SM_ROLE_SELECTION_EXEC,
116     PORT_ROLE_SELECTION_SM_ROLE_SELECTION
117 };
118 enum port_role_transition_state_machine {
119     PORT_ROLE_TRANSITION_SM_INIT,
120     PORT_ROLE_TRANSITION_SM_INIT_PORT_EXEC,
121     PORT_ROLE_TRANSITION_SM_DISABLE_PORT_EXEC,
122     PORT_ROLE_TRANSITION_SM_DISABLE_PORT,
123     PORT_ROLE_TRANSITION_SM_DISABLED_PORT_EXEC,
124     PORT_ROLE_TRANSITION_SM_DISABLED_PORT,
125     PORT_ROLE_TRANSITION_SM_ROOT_PORT_EXEC,
126     PORT_ROLE_TRANSITION_SM_ROOT_PORT,
127     PORT_ROLE_TRANSITION_SM_REROOT_EXEC,
128     PORT_ROLE_TRANSITION_SM_ROOT_AGREED_EXEC,
129     PORT_ROLE_TRANSITION_SM_ROOT_PROPOSED_EXEC,
130     PORT_ROLE_TRANSITION_SM_ROOT_FORWARD_EXEC,
131     PORT_ROLE_TRANSITION_SM_ROOT_LEARN_EXEC,
132     PORT_ROLE_TRANSITION_SM_REROOTED_EXEC,
133     PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT_EXEC,
134     PORT_ROLE_TRANSITION_SM_DESIGNATED_PORT,
135     PORT_ROLE_TRANSITION_SM_DESIGNATED_RETIRED_EXEC,
136     PORT_ROLE_TRANSITION_SM_DESIGNATED_SYNCED_EXEC,
137     PORT_ROLE_TRANSITION_SM_DESIGNATED_PROPOSE_EXEC,
138     PORT_ROLE_TRANSITION_SM_DESIGNATED_FORWARD_EXEC,
139     PORT_ROLE_TRANSITION_SM_DESIGNATED_LEARN_EXEC,
140     PORT_ROLE_TRANSITION_SM_DESIGNATED_DISCARD_EXEC,
141     PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT_EXEC,
142     PORT_ROLE_TRANSITION_SM_ALTERNATE_PORT,
143     PORT_ROLE_TRANSITION_SM_ALTERNATE_AGREED,
144     PORT_ROLE_TRANSITION_SM_ALTERNATE_PROPOSED_EXEC,
145     PORT_ROLE_TRANSITION_SM_BLOCK_PORT_EXEC,
146     PORT_ROLE_TRANSITION_SM_BLOCK_PORT,
147     PORT_ROLE_TRANSITION_SM_BACKUP_PORT_EXEC
148 };
149 enum port_state_transition_state_machine {
150     PORT_STATE_TRANSITION_SM_INIT,
151     PORT_STATE_TRANSITION_SM_DISCARDING_EXEC,
152     PORT_STATE_TRANSITION_SM_DISCARDING,
153     PORT_STATE_TRANSITION_SM_LEARNING_EXEC,
154     PORT_STATE_TRANSITION_SM_LEARNING,
155     PORT_STATE_TRANSITION_SM_FORWARDING_EXEC,
156     PORT_STATE_TRANSITION_SM_FORWARDING
157 };
158 enum topology_change_state_machine {
159     TOPOLOGY_CHANGE_SM_INIT,
160     TOPOLOGY_CHANGE_SM_INACTIVE_EXEC,
161     TOPOLOGY_CHANGE_SM_INACTIVE,
162     TOPOLOGY_CHANGE_SM_LEARNING_EXEC,
163     TOPOLOGY_CHANGE_SM_LEARNING,
164     TOPOLOGY_CHANGE_SM_DETECTED_EXEC,
165     TOPOLOGY_CHANGE_SM_ACTIVE_EXEC,
166     TOPOLOGY_CHANGE_SM_ACTIVE,
167     TOPOLOGY_CHANGE_SM_ACKNOWLEDGED_EXEC,
168     TOPOLOGY_CHANGE_SM_PROPAGATING_EXEC,
169     TOPOLOGY_CHANGE_SM_NOTIFIED_TC_EXEC,
170     TOPOLOGY_CHANGE_SM_NOTIFIED_TCN_EXEC,
171 };
172
173
174 /* [17.18.4, 17.13, Table 17-1]. */
175 struct rstp_times {
176     /* [17.13.5 - Bridge Forward Delay] The delay (expressed in seconds) used
177      * by STP Bridges (17.4) to transition Root and Designated Ports to
178      * Forwarding (Table 17-1).
179      * Default = 15.0 s. Values in range 4.0 - 30.0
180      */
181     uint16_t forward_delay;
182
183     /* [17.13.6 - Bridge Hello Time]
184      * The interval between periodic transmissions of Configuration Messages
185      * by Designated Ports (Table 17-1).
186      * Default = 2.0 s. Fixed value
187      */
188     uint16_t hello_time;
189
190     /* [17.13.8 - Bridge Max Age]
191      * The maximum age of the information transmitted by the Bridge when it is
192      * the Root Bridge (Table 17-1).
193      * Default = 20.0 s. Values in range 6.0 - 40.0 */
194     uint16_t max_age;
195
196     uint16_t message_age;
197 };
198
199 /* Priority vector [17.6] */
200 struct rstp_priority_vector {
201     rstp_identifier root_bridge_id;
202     uint32_t root_path_cost;
203     rstp_identifier designated_bridge_id;
204     uint16_t designated_port_id;
205     uint16_t bridge_port_id;
206 };
207
208 enum rstp_bpdu_type {
209     CONFIGURATION_BPDU = 0x0,
210     TOPOLOGY_CHANGE_NOTIFICATION_BPDU = 0x80,
211     RAPID_SPANNING_TREE_BPDU = 0x2
212 };
213
214 enum rstp_bpdu_flag {
215     BPDU_FLAG_TOPCHANGE = 0x01,
216     BPDU_FLAG_PROPOSAL = 0x02,
217     BPDU_FLAG_LEARNING = 0x10,
218     BPDU_FLAG_FORWARDING = 0x20,
219     BPDU_FLAG_AGREEMENT = 0x40,
220     BPDU_FLAG_TOPCHANGEACK = 0x80
221 };
222
223 /* Rapid Spanning Tree BPDU [9.3.3] */
224 OVS_PACKED(
225 struct rstp_bpdu {
226     ovs_be16 protocol_identifier;
227     uint8_t  protocol_version_identifier;
228     uint8_t  bpdu_type;
229     uint8_t  flags;
230     ovs_be64 root_bridge_id;
231     ovs_be32 root_path_cost;
232     ovs_be64 designated_bridge_id;
233     ovs_be16 designated_port_id;
234     ovs_be16  message_age;
235     ovs_be16  max_age;
236     ovs_be16  hello_time;
237     ovs_be16  forward_delay;
238     uint8_t  version1_length;
239     uint8_t  padding[7];
240 });
241
242 enum rstp_admin_point_to_point_mac_state {
243     RSTP_ADMIN_P2P_MAC_FORCE_TRUE,
244     RSTP_ADMIN_P2P_MAC_FORCE_FALSE,
245     RSTP_ADMIN_P2P_MAC_FORCE_AUTO
246 };
247
248 enum rstp_info_is {
249     INFO_IS_DISABLED,
250     INFO_IS_RECEIVED,
251     INFO_IS_AGED,
252     INFO_IS_MINE
253 };
254
255 enum rstp_rcvd_info {
256     SUPERIOR_DESIGNATED_INFO,
257     REPEATED_DESIGNATED_INFO,
258     INFERIOR_DESIGNATED_INFO,
259     INFERIOR_ROOT_ALTERNATE_INFO,
260     OTHER_INFO
261 };
262
263 struct rstp_port {
264     struct ovs_refcount ref_cnt;
265
266     struct rstp *rstp OVS_GUARDED_BY(rstp_mutex);
267     struct list node OVS_GUARDED_BY(rstp_mutex); /* Node in rstp->ports list. */
268     void *aux OVS_GUARDED_BY(rstp_mutex);
269     struct rstp_bpdu received_bpdu_buffer OVS_GUARDED_BY(rstp_mutex);
270     /*************************************************************************
271      * MAC status parameters
272      ************************************************************************/
273     /* [6.4.2 - MAC_Operational]
274      * The value of this parameter is TRUE if [...] the MAC entity can be used
275      * to transmit and/or receive frames, and its use is permitted by
276      * management.
277      */
278     bool mac_operational OVS_GUARDED_BY(rstp_mutex);
279
280     /* [14.8.2.2] Administrative Bridge Port State */
281     bool is_administrative_bridge_port OVS_GUARDED_BY(rstp_mutex);
282
283     /* [6.4.3 - operPointToPointMAC]
284      *  a) True. The MAC is connected to a point-to-point LAN; i.e., there is
285      *     at most one other system attached to the LAN.
286      *  b) False. The MAC is connected to a non-point-to-point LAN; i.e.,
287      *     there can be more than one other system attached to the LAN.
288      *
289      *  If adminPointToPointMAC is set to ForceTrue, then operPointToPointMAC
290      *  shall be set True. If adminPointToPointMAC is set to ForceFalse, then
291      *  operPointToPointMAC shall be set False.
292      */
293     bool oper_point_to_point_mac OVS_GUARDED_BY(rstp_mutex);
294
295     /* [6.4.3 - adminPointToPointMAC]
296      *  a) ForceTrue. The administrator requires the MAC to be treated as if it
297      *     is connected to a point-to-point LAN, regardless of any indications
298      *     to the contrary that are generated by the MAC entity.
299      *  b) ForceFalse. The administrator requires the MAC to be treated as
300      *     connected to a non-point-to-point LAN, regardless of any indications
301      *     to the contrary that are generated by the MAC entity.
302      *  c) Auto. The administrator requires the point-to-point status of the
303      *     MAC to be determined in accordance with the specific MAC procedures
304      *     defined in 6.5.
305      */
306     enum rstp_admin_point_to_point_mac_state admin_point_to_point_mac OVS_GUARDED_BY(rstp_mutex);
307
308
309     /*************************************************************************
310      * [17.3 - RSTP performance parameters] Set by management actions on the
311      * bridge
312      *************************************************************************/
313
314     /* [17.13.1 - Admin Edge Port]
315      * The AdminEdgePort parameter for the Port (14.8.2).
316      */
317     bool admin_edge OVS_GUARDED_BY(rstp_mutex);
318
319     /* [17.13.3 - AutoEdge]
320      *  The AutoEdgePort parameter for the Port (14.8.2).
321      */
322     bool auto_edge OVS_GUARDED_BY(rstp_mutex);
323
324
325     /*************************************************************************
326      * The following variables are set by management actions on the bridge
327      ************************************************************************/
328
329     /* Port number and priority
330      * >=1 (max 12 bits [9.2.7])
331      */
332     uint16_t port_number OVS_GUARDED_BY(rstp_mutex);
333
334     /* Port priority
335      * Range: 0-240 in steps of 16 (table 17-2)
336      */
337     uint8_t priority OVS_GUARDED_BY(rstp_mutex);
338
339     /* [17.13.11 - PortPathCost]
340      * The Port's contribution, when it is the Root Port, to the Root Path Cost
341      * (17.3.1, 17.5, 17.6) for the Bridge.
342      */
343     uint32_t port_path_cost OVS_GUARDED_BY(rstp_mutex);
344
345     /*************************************************************************
346      * The following variables are defined in [17.17 - State machine timers]
347      ************************************************************************/
348     /* [17.17.1 - edgeDelayWhile]
349      * The Edge Delay timer. The time remaining, in the absence of a received
350      * BPDU, before this port is identified as an operEdgePort.
351      */
352     uint16_t edge_delay_while OVS_GUARDED_BY(rstp_mutex);
353
354     /* [17.17.2 - fdWhile]
355      * The Forward Delay timer. Used to delay Port State transitions until
356      * other Bridges have received spanning tree information.
357      */
358     uint16_t fd_while OVS_GUARDED_BY(rstp_mutex);
359
360     /* [17.17.3 - helloWhen]
361      * The Hello timer. Used to ensure that at least one BPDU is transmitted by
362      * a Designated Port in each HelloTime period.
363      */
364     uint16_t hello_when OVS_GUARDED_BY(rstp_mutex);
365
366     /* [17.17.4 - mdelayWhile]
367      * The Migration Delay timer. Used by the Port Protocol Migration state
368      * machine to allow time for another RSTP Bridge on the same LAN to
369      * synchronize its migration state with this Port before the receipt of a
370      * BPDU can cause this Port to change the BPDU types it transmits.
371      * Initialized to MigrateTime (17.13.9).
372      */
373     uint16_t mdelay_while OVS_GUARDED_BY(rstp_mutex);
374
375     /* [17.17.5 - rbWhile]
376      * The Recent Backup timer. Maintained at its initial value, twice
377      * HelloTime, while the Port is a Backup Port.
378      */
379     uint16_t rb_while OVS_GUARDED_BY(rstp_mutex);
380
381     /* [17.17.6 - rcvdInfoWhile]
382      * The Received Info timer. The time remaining before the spanning tree
383      * information received by this Port [portPriority (17.19.21) and portTimes
384      * (17.19.22)] is aged out if not refreshed by the receipt of a further
385      * Configuration Message.
386      */
387     uint16_t rcvd_info_while OVS_GUARDED_BY(rstp_mutex);
388
389     /* [17.17.7 - rrWhile]
390      * The Recent Root timer.
391      */
392     uint16_t rr_while OVS_GUARDED_BY(rstp_mutex);
393
394     /* [17.17.8 - tcWhile]
395      * The Topology Change timer. TCN Messages are sent while this timer is
396      * running.
397      */
398     uint16_t tc_while OVS_GUARDED_BY(rstp_mutex);
399
400
401     /*************************************************************************
402      * The following variables are defined in [17.19 - Per-Port variables]
403      ************************************************************************/
404
405     /* [17.19.1 - ageingTime]
406      * Filtering database entries for this Port are aged out after ageingTime
407      * has elapsed since they were first created or refreshed by the Learning
408      * Process.
409      * The value of this parameter is normally Ageing Time (7.9.2, Table 7-5),
410      * and is changed to FwdDelay (17.20.6) for a period of FwdDelay after
411      * fdbFlush (17.19.7) is set by the topology change state machine if
412      * stpVersion (17.19.7) is TRUE.
413      */
414     uint32_t ageing_time OVS_GUARDED_BY(rstp_mutex);
415
416     /* [17.19.2 - agree]
417      * Set if synced is set for all other Ports. An RST BPDU with the Agreement
418      * flag set is transmitted and proposed is reset when agree is first set,
419      * and when proposed is set.
420      * Initialized by Port Information state machine.
421      */
422     bool agree OVS_GUARDED_BY(rstp_mutex);
423
424     /* [17.19.3 - agreed]
425      * Set when an RST BPDU is received with a Port Role of Root, Alternate, or
426      * Backup Port, the Agreement flag set, and a message priority the same or
427      * worse than the port priority. When agreed is set, the Designated Port
428      * knows that its neighbouring Bridge has confirmed that it can proceed to
429      * the Forwarding state without further delay.
430      * Initialized by Port Information state machine.
431      */
432     bool agreed OVS_GUARDED_BY(rstp_mutex);
433
434     /* [17.19.4 - designatedPriority]
435      * The first four components of the Port's designated priority vector
436      * value, as defined in 17.6. The fifth component of the designated
437      * priority vector value is portId (17.19.19).
438      * (Fifth component of the structure must not be used)
439      */
440     struct rstp_priority_vector designated_priority_vector OVS_GUARDED_BY(rstp_mutex);
441
442     /* [17.19.5 - designatedTimes]
443      * The designatedTimes variable comprises the set of timer parameter values
444      * (Message Age, Max Age, Forward Delay, and Hello Time) that used to
445      * update Port Times when updtInfo is set. Updated by the updtRolesTree()
446      * procedure (17.21.25).
447      */
448     struct rstp_times designated_times OVS_GUARDED_BY(rstp_mutex);
449
450     /* [17.19.6 - disputed] */
451     bool disputed OVS_GUARDED_BY(rstp_mutex);
452
453     /* [17.19.7 - fdbFlush]
454      * A boolean. Set by the topology change state machine to instruct the
455      * filtering database to remove all entries for this Port, immediately if
456      * rstpVersion (17.20.11) is TRUE, or by rapid ageing (17.19.1) if
457      * stpVersion (17.20.12) is TRUE. Reset by the filtering database once the
458      * entries are
459      * removed if rstpVersion is TRUE, and immediately if stpVersion is TRUE.
460      */
461     uint8_t fdb_flush OVS_GUARDED_BY(rstp_mutex);
462
463     /* [17.19.8 - forward]
464      * Initialized by Port State Transition state machine.
465      */
466     bool forward OVS_GUARDED_BY(rstp_mutex);
467
468     /* [17.19.9 - forwarding]
469      * Initialized by Port State Transition state machine.
470      */
471     bool forwarding OVS_GUARDED_BY(rstp_mutex);
472
473     /* [17.19.10 - infoIs]
474      * A variable that takes the values Mine, Aged, Received, or Disabled, to
475      * indicate the origin/state of the Port's Spanning Tree information
476      * (portInfo) held for the Port, as follows:
477      *  a) If infoIs is Received, the port has received current (not aged out)
478      *     information from the Designated Bridge for the attached LAN (a
479      *     point-to-point bridge link being a special case of a LAN).
480      *  b) If infoIs is Mine, information for the port has been derived from
481      *     the Root Port for the Bridge (with the addition of root port cost
482      *     information). This includes the possibility that the Root Port is
483      *     "Port 0," i.e., the bridge is the Root Bridge for the Bridged Local
484      *     Area Network.
485      *  c) If infoIs is Aged, information from the Root Bridge has been aged
486      *     out. Just as for "reselect" (see 17.19.34), the state machine does
487      *     not formally allow the "Aged" state to persist. However, if there is
488      *     a delay in recomputing the new root port, correct processing of a
489      *     received BPDU is specified.
490      *  d) Finally if the port is disabled, infoIs is Disabled.
491      */
492     enum rstp_info_is info_is OVS_GUARDED_BY(rstp_mutex);
493
494     /* [17.19.11 - learn]
495      * Initialized by Port State Transition state machine.
496      */
497     bool learn OVS_GUARDED_BY(rstp_mutex);
498
499     /* [17.19.12 - learning]
500      * Initialized by Port State Transition state machine.
501      */
502     bool learning OVS_GUARDED_BY(rstp_mutex);
503
504     /* [17.19.13 - mcheck]
505      * A boolean. May be set by management to force the Port Protocol Migration
506      * state machine to transmit RST BPDUs for a MigrateTime (17.13.9) period,
507      * to test whether all STP Bridges (17.4) on the attached LAN have been
508      * removed and the Port can continue to transmit RSTP BPDUs. Setting mcheck
509      * has no effect if stpVersion (17.20.12) is TRUE, i.e., the Bridge is
510      * operating in STP Compatibility mode.
511      */
512     bool mcheck OVS_GUARDED_BY(rstp_mutex);
513
514     /* [17.19.14 - msgPriority]
515      * The first four components of the message priority vector conveyed in a
516      * received BPDU, as defined in 17.6.
517      * (Fifth component of the structure must not be used).
518      */
519     struct rstp_priority_vector msg_priority OVS_GUARDED_BY(rstp_mutex);
520
521     /* [17.19.15 - msgTimes]
522      * The msgTimes variable comprises the timer parameter values (Message Age,
523      * Max Age, Forward Delay, and Hello Time) conveyed in a received BPDU.
524      */
525     struct rstp_times msg_times OVS_GUARDED_BY(rstp_mutex);
526
527     /* [17.19.16 - newInfo]
528      * A boolean. Set if a BPDU is to be transmitted. Reset by the Port
529      * Transmit state machine.
530      */
531     bool new_info OVS_GUARDED_BY(rstp_mutex);
532
533     /* [17.19.17 - operEdge]
534      * A boolean. The value of the operEdgePort parameter, as determined by the
535      * operation of the Bridge Detection state machine (17.25).
536      */
537     bool oper_edge OVS_GUARDED_BY(rstp_mutex);
538
539     /* [17.19.18 - portEnabled]
540      * A boolean. Set if the Bridge's MAC Relay Entity and Spanning Tree
541      * Protocol Entity can use the MAC Service provided by the Port's MAC
542      * entity to transmit and receive frames to and from the attached LAN,
543      * i.e., portEnabled is TRUE if and only if:
544      *    a) MAC_Operational (6.4.2) is TRUE; and
545      *    b) Administrative Bridge Port State (14.8.2.2) for the Port is
546      *       Enabled; and
547      *    c) AuthControlledPortStatus is Authorized [if the port is a network
548      *       access port (IEEE Std 802.1X)].
549      */
550     bool port_enabled OVS_GUARDED_BY(rstp_mutex);
551
552     /* [17.19.19 - portId]
553      * The Port Identifier. This variable forms the fifth component of the port
554      * priority and designated priority vectors defined in 17.6.
555      */
556     uint16_t port_id OVS_GUARDED_BY(rstp_mutex);
557
558     /* [17.19.21 - portPriority]
559      * The first four components of the Port's port priority vector value, as
560      * defined in 17.6.
561      * (Fifth component of the structure must not be used)
562      */
563     struct rstp_priority_vector port_priority OVS_GUARDED_BY(rstp_mutex);
564
565     /* [17.19.22 - portTimes]
566      * The portTimes variable comprises the Port's timer parameter values
567      * (Message Age, Max Age, Forward Delay, and Hello Time). These timer
568      * values are used in BPDUs transmitted from the Port.
569      */
570     struct rstp_times port_times OVS_GUARDED_BY(rstp_mutex);
571
572     /* [17.19.23 - proposed]
573      * Set when an RST BPDU with a Designated Port role and the Proposal flag
574      * set is received. If agree is not set, proposed causes sync to be set for
575      * all other Ports.of the Bridge.
576      */
577     bool proposed OVS_GUARDED_BY(rstp_mutex);
578
579     /* [17.19.24 - proposing]
580      * Set by a Designated Port that is not Forwarding, and conveyed to the
581      * Root Port or Alternate Port of a neighboring Bridge in the Proposal flag
582      * of an RST BPDU (9.3.3).
583      */
584     bool proposing OVS_GUARDED_BY(rstp_mutex);
585
586     /* [17.19.25 - rcvdBPDU]
587      * A boolean. Set by system dependent processes, this variable notifies the
588      * Port Receive state machine (17.23) when a valid (9.3.4) Configuration,
589      * TCN, or RST BPDU (9.3.1, 9.3.2, 9.3.3) is received on the Port. Reset
590      * by the Port Receive state machine.
591      */
592     bool rcvd_bpdu OVS_GUARDED_BY(rstp_mutex);
593
594     /* [17.19.26 - rcvdInfo]
595      * Set to the result of the rcvInfo() procedure (17.21.8).
596      */
597     enum rstp_rcvd_info rcvd_info OVS_GUARDED_BY(rstp_mutex);
598
599     /* [17.19.27 - rcvdMsg] */
600     bool rcvd_msg OVS_GUARDED_BY(rstp_mutex);
601
602     /* [17.19.28 - rcvdRSTP] */
603     bool rcvd_rstp OVS_GUARDED_BY(rstp_mutex);
604
605     /* [17.19.29 - rcvdSTP] */
606     bool rcvd_stp OVS_GUARDED_BY(rstp_mutex);
607
608     /* [17.19.30 - rcvdTc] */
609     bool rcvd_tc OVS_GUARDED_BY(rstp_mutex);
610
611     /* [17.19.31 - rcvdTcAck] */
612     bool rcvd_tc_ack OVS_GUARDED_BY(rstp_mutex);
613
614     /* [17.19.32 - rcvdTcn] */
615     bool rcvd_tcn OVS_GUARDED_BY(rstp_mutex);
616
617     /* [17.19.33 - reRoot] */
618     bool re_root OVS_GUARDED_BY(rstp_mutex);
619
620     /* [17.19.34 - reselect] */
621     bool reselect OVS_GUARDED_BY(rstp_mutex);
622
623     /* [17.19.35 - role]
624      * The assigned Port Role (17.7).
625      */
626     enum rstp_port_role role OVS_GUARDED_BY(rstp_mutex);
627
628     /* [17.19.36 - selected]
629      * A boolean. See 17.28, 17.21.16.
630      */
631     bool selected OVS_GUARDED_BY(rstp_mutex);
632
633     /* [17.19.37 - selectedRole]
634      * The newly computed role for the Port (17.7, 17.28, 17.21.25, 17.19.35).
635      */
636     enum rstp_port_role selected_role OVS_GUARDED_BY(rstp_mutex);
637
638     /* [17.19.38 - sendRSTP]
639      * A boolean. See 17.24, 17.26.
640      */
641     bool send_rstp OVS_GUARDED_BY(rstp_mutex);
642
643     /* [17.19.39 - sync]
644      * A boolean. See 17.10.
645      */
646     bool sync OVS_GUARDED_BY(rstp_mutex);
647
648     /* [17.19.40 - synced]
649      * A boolean. See 17.10.
650      */
651     bool synced OVS_GUARDED_BY(rstp_mutex);
652
653     /* [17.19.41 - tcAck]
654      * A boolean. Set if a Configuration Message with a topology change
655      * acknowledge flag set is to be transmitted.
656      */
657     bool tc_ack OVS_GUARDED_BY(rstp_mutex);
658
659     /* [17.19.42 - tcProp]
660      * A boolean. Set by the Topology Change state machine of any other Port,
661      * to indicate that a topology change should be propagated through this
662      * Port.
663      */
664     bool tc_prop OVS_GUARDED_BY(rstp_mutex);
665
666     /* [17.19.43 - tick]
667      * A boolean. See 17.22.
668      */
669     bool tick OVS_GUARDED_BY(rstp_mutex);
670
671     /* [17.19.44 - txCount]
672      * A counter. Incremented by the Port Transmission (17.26) state machine on
673      * every BPDU transmission, and decremented used by the Port Timers state
674      * machine (17.22) once a second. Transmissions are delayed if txCount
675      * reaches TxHoldCount (17.13.12).
676      */
677     uint16_t tx_count OVS_GUARDED_BY(rstp_mutex);
678
679     /* [17.19.45 - updtInfo]
680      * A boolean. Set by the Port Role Selection state machine (17.28,
681      * 17.21.25) to tell the Port Information state machine that it should copy
682      * designatedPriority to portPriority and designatedTimes to portTimes.
683      */
684     bool updt_info OVS_GUARDED_BY(rstp_mutex);
685
686     /* Counter for RSTP received frames - for rstpd */
687     uint32_t rx_rstp_bpdu_cnt;
688
689     /* Counter for bad RSTP received frames */
690     uint32_t error_count OVS_GUARDED_BY(rstp_mutex);
691
692     /* [14.8.2.1.3] Outputs
693      * a) Uptime count in seconds of the time elapsed since the Port was last
694      *    reset or initialized.
695      */
696     uint32_t uptime OVS_GUARDED_BY(rstp_mutex);
697
698     enum rstp_state rstp_state OVS_GUARDED_BY(rstp_mutex);
699     bool state_changed OVS_GUARDED_BY(rstp_mutex);
700
701     /* Per-port state machines state */
702     enum port_receive_state_machine port_receive_sm_state OVS_GUARDED_BY(rstp_mutex);
703     enum port_protocol_migration_state_machine port_protocol_migration_sm_state OVS_GUARDED_BY(rstp_mutex);
704     enum bridge_detection_state_machine bridge_detection_sm_state OVS_GUARDED_BY(rstp_mutex);
705     enum port_transmit_state_machine port_transmit_sm_state OVS_GUARDED_BY(rstp_mutex);
706     enum port_information_state_machine port_information_sm_state OVS_GUARDED_BY(rstp_mutex);
707     enum port_role_transition_state_machine port_role_transition_sm_state OVS_GUARDED_BY(rstp_mutex);
708     enum port_state_transition_state_machine port_state_transition_sm_state OVS_GUARDED_BY(rstp_mutex);
709     enum topology_change_state_machine topology_change_sm_state OVS_GUARDED_BY(rstp_mutex);
710 };
711
712 struct rstp {
713     struct list node OVS_GUARDED_BY(rstp_mutex);   /* In rstp instances list */
714     char *name;     /* Bridge name. */
715
716     /* Changes in last SM execution. */
717     bool changes OVS_GUARDED_BY(rstp_mutex);
718
719     /* Per-bridge state machines state */
720     enum port_role_selection_state_machine port_role_selection_sm_state OVS_GUARDED_BY(rstp_mutex);
721
722     /* Bridge MAC address
723      * (stored in the least significant 48 bits of rstp_identifier).
724      */
725     rstp_identifier address OVS_GUARDED_BY(rstp_mutex); /* [7.12.5] */
726
727     /* Bridge priority */
728     uint16_t priority OVS_GUARDED_BY(rstp_mutex);      /* Valid values: 0-61440 in steps of 4096 */
729
730     /*************************************************************************
731      * [17.3 - RSTP performance parameters]
732      ************************************************************************/
733
734     /* [17.13]
735      * The Spanning Tree Protocol Entity shall be reinitialized, as specified
736      * by the assertion of BEGIN (17.18.1) in the state machine specification,
737      * if the following parameters are modified:
738      *  a) Force Protocol Version (17.13.4)
739      *
740      * The spanning tree priority vectors and Port Role assignments for a
741      * Bridge shall be recomputed, as specified by the operation of the Port
742      * Role Selection state machine (17.28) by clearing selected (17.19.36) and
743      * setting reselect (17.19.34) for any Port or Ports for which the
744      * following parameters are modified:
745      *  b) Bridge Identifier Priority (17.13.7)
746      *  c) Port Identifier Priority (17.13.10)
747      *  d) Port Path Cost (17.13.11)
748      *
749      * If the Transmit Hold Count is modified the value of txCount (17.19.44)
750      * for all Ports shall be set to zero.
751      *
752      * The RSTP specification permits changes in other performance parameters
753      * without exceptional actions.
754      */
755
756
757     /* [17.13.2 - Ageing Time]
758      * The Ageing Time parameter for the Bridge (7.9.2, Table 7-5).
759      */
760     uint32_t ageing_time OVS_GUARDED_BY(rstp_mutex);
761
762     /* [17.13.4 - Force Protocol Version]
763      * The Force Protocol Version parameter for the Bridge (17.4, 14.8.1).
764      * This can take the value 0 (STP Compatibility mode) or 2 (the default,
765      * normal operation).
766      */
767     enum rstp_force_protocol_version force_protocol_version OVS_GUARDED_BY(rstp_mutex);
768
769     /* [17.13.5 - Bridge Forward Delay]
770      *  The delay used by STP Bridges (17.4) to transition Root and Designated
771      * Ports to Forwarding (Table 17-1).
772      */
773     uint16_t bridge_forward_delay OVS_GUARDED_BY(rstp_mutex);
774
775     /* [17.13.6 - Bridge Hello Time]
776      *  The interval between periodic transmissions of Configuration Messages
777      * by Designated Ports (Table 17-1).
778      */
779     uint16_t bridge_hello_time OVS_GUARDED_BY(rstp_mutex);
780
781     /* [17.13.8 - Bridge Max Age]
782      * The maximum age of the information transmitted by the Bridge when it is
783      * the Root Bridge (Table 17-1).
784      */
785     uint16_t bridge_max_age OVS_GUARDED_BY(rstp_mutex);
786
787     /* [17.13.9 - Migrate Time]
788      * The initial value of the mdelayWhile and edgeDelayWhile timers (17.17.4,
789      * 17.17.1), fixed for all RSTP implementations conforming to this
790      * specification (Table 17-1).
791      */
792     uint16_t migrate_time OVS_GUARDED_BY(rstp_mutex);
793
794     /* [17.13.12 - Transmit Hold Count]
795      * The Transmit Hold Count (Table 17-1) used by the Port Transmit state
796      * machine to limit transmission rate.
797      */
798     uint16_t transmit_hold_count OVS_GUARDED_BY(rstp_mutex);
799
800
801     /*************************************************************************
802      * The following variables are defined in [17.18 - Per-Bridge variables]
803      ************************************************************************/
804
805     /* [17.18.1 - BEGIN]
806      * A Boolean controlled by the system initialization (17.16). If TRUE
807      * causes all state machines, including per Port state machines, to
808      * continuously execute their initial state.
809      */
810     bool begin OVS_GUARDED_BY(rstp_mutex);
811
812     /* [17.18.2 BridgeIdentifier]
813      * The unique Bridge Identifier assigned to this Bridge, comprising two
814      * components: the Bridge Identifier Priority, which may be modified by
815      * management (see 9.2.5 and 14.8.1.2) and is the more significant when
816      * Bridge Identifiers are compared, and a component derived from the Bridge
817      * Address (7.12.5), which guarantees uniqueness of the Bridge Identifiers
818      * of different Bridges.
819      */
820     rstp_identifier bridge_identifier OVS_GUARDED_BY(rstp_mutex);
821
822     /* [17.8.3 BridgePriority]
823      * The bridge priority vector, as defined in 17.6. The first (RootBridgeID)
824      * and third (DesignatedBridgeID) components are both equal to the value
825      * of the Bridge Identifier (17.18.2). The other components are zero.
826      */
827     struct rstp_priority_vector bridge_priority OVS_GUARDED_BY(rstp_mutex);
828
829     /* [17.18.4 - BridgeTimes]
830      * BridgeTimes comprises four components: the current values of Bridge
831      * Forward Delay, Bridge Hello Time, Bridge Max Age (17.13, Table 17-1),
832      * and a Message Age of zero.
833      */
834     struct rstp_times bridge_times OVS_GUARDED_BY(rstp_mutex);
835
836     /* [17.18.6 - rootPriority]
837      * The first four components of the Bridge's root priority vector, as
838      * defined in 17.6.
839      */
840     struct rstp_priority_vector root_priority OVS_GUARDED_BY(rstp_mutex);
841
842     /* [17.18.5 - rootPortId]
843      * The Port Identifier of the Root Port. This is the fifth component of
844      * the root priority vector, as defined in 17.6.
845      */
846     uint16_t root_port_id OVS_GUARDED_BY(rstp_mutex);
847
848     /* [17.18.7 - rootTimes]
849      * The rootTimes variable comprises the Bridge's operational timer
850      * parameter values (Message Age, Max Age, Forward Delay, and Hello Time),
851      * derived from the values stored in portTimes (17.19.22) for the Root Port
852      * or from BridgeTimes (17.18.4).
853      */
854     struct rstp_times root_times OVS_GUARDED_BY(rstp_mutex);
855
856     /* 17.20 State machine conditions and parameters */
857
858     /* [17.20.11] rstpVersion
859      * TRUE if Force Protocol Version (17.13.4) is greater than or equal to 2.
860      */
861     bool rstp_version OVS_GUARDED_BY(rstp_mutex);
862
863     /* [17.20.12] stpVersion
864      * TRUE if Force Protocol Version (17.13.4) is less than 2.
865      */
866     bool stp_version OVS_GUARDED_BY(rstp_mutex);
867
868     /* Ports */
869     struct list ports OVS_GUARDED_BY(rstp_mutex);
870     uint16_t ports_count OVS_GUARDED_BY(rstp_mutex);
871
872     struct ovs_refcount ref_cnt;
873
874     /* Interface to client. */
875     void (*send_bpdu)(struct ofpbuf *bpdu, int port_no, void *aux);
876     void *aux;
877 };
878
879 #endif /* rstp-common.h */