]>
Commit | Line | Data |
---|---|---|
9efd308e | 1 | /* |
eb1746e6 | 2 | * Copyright (c) 2011-2015 M3S, Srl - Italy |
9efd308e DV |
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) public interface (header | |
19 | * file). | |
20 | * | |
21 | * Authors: | |
22 | * Martino Fornasa <mf@fornasa.it> | |
23 | * Daniele Venturino <daniele.venturino@m3s.it> | |
eb1746e6 | 24 | * Carlo Andreotti <c.andreotti@m3s.it> |
9efd308e DV |
25 | * |
26 | * References to IEEE 802.1D-2004 standard are enclosed in square brackets. | |
27 | * E.g. [17.3], [Table 17-1], etc. | |
28 | * | |
29 | */ | |
30 | ||
31 | #ifndef RSTP_H | |
32 | #define RSTP_H 1 | |
33 | ||
34 | #include <stdint.h> | |
35 | #include <stdbool.h> | |
36 | #include "compiler.h" | |
37 | #include "util.h" | |
38 | ||
f025bcb7 JR |
39 | /* Thread Safety: Callers passing in RSTP and RSTP port object |
40 | * pointers must hold a reference to the passed object to ensure that | |
41 | * the object does not become stale while it is being accessed. */ | |
42 | ||
43 | extern struct ovs_mutex rstp_mutex; | |
44 | ||
9efd308e DV |
45 | #define RSTP_MAX_PORTS 4095 |
46 | ||
cf62fa4c | 47 | struct dp_packet; |
9efd308e DV |
48 | |
49 | /* Bridge priority defaults [Table 17-2] */ | |
50 | #define RSTP_MIN_PRIORITY 0 | |
51 | #define RSTP_MAX_PRIORITY 61440 | |
52 | #define RSTP_PRIORITY_STEP 4096 | |
53 | #define RSTP_DEFAULT_PRIORITY 32768 | |
54 | ||
55 | /* Port priority defaults [Table 17-2] */ | |
56 | #define RSTP_MIN_PORT_PRIORITY 0 | |
57 | #define RSTP_MAX_PORT_PRIORITY 240 | |
58 | #define RSTP_STEP_PORT_PRIORITY 16 | |
59 | #define RSTP_DEFAULT_PORT_PRIORITY 128 | |
60 | ||
61 | /* Performance parameters defaults. [Table 7-5] and [Table 17-1] | |
62 | * These values are expressed in seconds. | |
63 | */ | |
64 | #define RSTP_DEFAULT_AGEING_TIME 300 | |
65 | #define RSTP_MIN_AGEING_TIME 10 | |
66 | #define RSTP_MAX_AGEING_TIME 1000000 | |
67 | ||
68 | #define RSTP_DEFAULT_BRIDGE_MAX_AGE 20 | |
69 | #define RSTP_MIN_BRIDGE_MAX_AGE 6 | |
70 | #define RSTP_MAX_BRIDGE_MAX_AGE 40 | |
71 | ||
72 | #define RSTP_DEFAULT_BRIDGE_FORWARD_DELAY 15 | |
73 | #define RSTP_MIN_BRIDGE_FORWARD_DELAY 4 | |
74 | #define RSTP_MAX_BRIDGE_FORWARD_DELAY 30 | |
75 | ||
76 | #define RSTP_DEFAULT_TRANSMIT_HOLD_COUNT 6 | |
77 | #define RSTP_MIN_TRANSMIT_HOLD_COUNT 1 | |
78 | #define RSTP_MAX_TRANSMIT_HOLD_COUNT 10 | |
79 | ||
80 | #define RSTP_BRIDGE_HELLO_TIME 2 /* Value is fixed [Table 17-1] */ | |
81 | ||
82 | #define RSTP_MIGRATE_TIME 3 /* Value is fixed [Table 17-1] */ | |
83 | ||
84 | /* Port path cost [Table 17-3] */ | |
85 | #define RSTP_MIN_PORT_PATH_COST 1 | |
86 | #define RSTP_MAX_PORT_PATH_COST 200000000 | |
87 | #define RSTP_DEFAULT_PORT_PATH_COST 200000 | |
88 | ||
89 | /* RSTP Bridge identifier [9.2.5]. Top four most significant bits are a | |
90 | * priority value. The next most significant twelve bits are a locally | |
91 | * assigned system ID extension. Bottom 48 bits are MAC address of bridge. | |
92 | */ | |
93 | typedef uint64_t rstp_identifier; | |
94 | ||
95 | #define RSTP_ID_FMT "%01"PRIx8".%03"PRIx16".%012"PRIx64 | |
96 | #define RSTP_ID_ARGS(rstp_id) \ | |
97 | (uint8_t)((rstp_id) >> 60), \ | |
98 | (uint16_t)(((rstp_id) & 0x0fff000000000000ULL) >> 48), \ | |
99 | (uint64_t)((rstp_id) & 0xffffffffffffULL) | |
100 | ||
101 | #define RSTP_PORT_ID_FMT "%04"PRIx16 | |
102 | ||
103 | enum rstp_state { | |
104 | RSTP_DISABLED, | |
105 | RSTP_LEARNING, | |
106 | RSTP_FORWARDING, | |
107 | RSTP_DISCARDING | |
108 | }; | |
109 | ||
110 | /* Force Protocol Version [17.13.4] */ | |
111 | enum rstp_force_protocol_version { | |
112 | FPV_STP_COMPATIBILITY = 0, | |
113 | FPV_DEFAULT = 2 | |
114 | }; | |
115 | ||
116 | enum rstp_port_role { | |
117 | ROLE_ROOT, | |
118 | ROLE_DESIGNATED, | |
119 | ROLE_ALTERNATE, | |
120 | ROLE_BACKUP, | |
121 | ROLE_DISABLED | |
122 | }; | |
123 | ||
67e8c1ac JR |
124 | enum rstp_admin_point_to_point_mac_state { |
125 | RSTP_ADMIN_P2P_MAC_FORCE_FALSE, | |
126 | RSTP_ADMIN_P2P_MAC_FORCE_TRUE, | |
127 | RSTP_ADMIN_P2P_MAC_AUTO | |
128 | }; | |
129 | ||
9efd308e DV |
130 | struct rstp; |
131 | struct rstp_port; | |
132 | struct ofproto_rstp_settings; | |
133 | ||
134 | const char *rstp_state_name(enum rstp_state); | |
f025bcb7 | 135 | const char *rstp_port_role_name(enum rstp_port_role); |
8fb76a0b JR |
136 | static inline bool rstp_forward_in_state(enum rstp_state); |
137 | static inline bool rstp_learn_in_state(enum rstp_state); | |
138 | static inline bool rstp_should_manage_bpdu(enum rstp_state state); | |
9efd308e | 139 | |
f025bcb7 JR |
140 | void rstp_init(void) |
141 | OVS_EXCLUDED(rstp_mutex); | |
9efd308e DV |
142 | |
143 | struct rstp * rstp_create(const char *, rstp_identifier bridge_id, | |
cf62fa4c | 144 | void (*send_bpdu)(struct dp_packet *, void *port_aux, |
6b90bc57 | 145 | void *rstp_aux), |
f025bcb7 JR |
146 | void *aux) |
147 | OVS_EXCLUDED(rstp_mutex); | |
4b30ba05 | 148 | |
f025bcb7 JR |
149 | struct rstp *rstp_ref(struct rstp *) |
150 | OVS_EXCLUDED(rstp_mutex); | |
151 | void rstp_unref(struct rstp *) | |
152 | OVS_EXCLUDED(rstp_mutex); | |
9efd308e DV |
153 | |
154 | /* Functions used outside RSTP, to call functions defined in | |
155 | rstp-state-machines.h */ | |
f025bcb7 JR |
156 | void rstp_tick_timers(struct rstp *) |
157 | OVS_EXCLUDED(rstp_mutex); | |
158 | void rstp_port_received_bpdu(struct rstp_port *, const void *bpdu, | |
159 | size_t bpdu_size) | |
160 | OVS_EXCLUDED(rstp_mutex); | |
66ff280d | 161 | void *rstp_check_and_reset_fdb_flush(struct rstp *, struct rstp_port **) |
f025bcb7 JR |
162 | OVS_EXCLUDED(rstp_mutex); |
163 | void *rstp_get_next_changed_port_aux(struct rstp *, struct rstp_port **) | |
164 | OVS_EXCLUDED(rstp_mutex); | |
9efd308e | 165 | void rstp_port_set_mac_operational(struct rstp_port *, |
f025bcb7 JR |
166 | bool new_mac_operational) |
167 | OVS_EXCLUDED(rstp_mutex); | |
2372c146 JR |
168 | bool rstp_shift_root_learned_address(struct rstp *) |
169 | OVS_EXCLUDED(rstp_mutex); | |
170 | void *rstp_get_old_root_aux(struct rstp *) | |
171 | OVS_EXCLUDED(rstp_mutex); | |
172 | void *rstp_get_new_root_aux(struct rstp *) | |
173 | OVS_EXCLUDED(rstp_mutex); | |
174 | void rstp_reset_root_changed(struct rstp *) | |
175 | OVS_EXCLUDED(rstp_mutex); | |
9efd308e DV |
176 | |
177 | /* Bridge setters */ | |
f025bcb7 JR |
178 | void rstp_set_bridge_address(struct rstp *, rstp_identifier bridge_address) |
179 | OVS_EXCLUDED(rstp_mutex); | |
180 | void rstp_set_bridge_priority(struct rstp *, int new_priority) | |
181 | OVS_EXCLUDED(rstp_mutex); | |
182 | void rstp_set_bridge_ageing_time(struct rstp *, int new_ageing_time) | |
183 | OVS_EXCLUDED(rstp_mutex); | |
9efd308e | 184 | void rstp_set_bridge_force_protocol_version(struct rstp *, |
f025bcb7 JR |
185 | enum rstp_force_protocol_version) |
186 | OVS_EXCLUDED(rstp_mutex); | |
187 | void rstp_set_bridge_max_age(struct rstp *, int new_max_age) | |
188 | OVS_EXCLUDED(rstp_mutex); | |
189 | void rstp_set_bridge_forward_delay(struct rstp *, int new_forward_delay) | |
190 | OVS_EXCLUDED(rstp_mutex); | |
9efd308e | 191 | void rstp_set_bridge_transmit_hold_count(struct rstp *, |
f025bcb7 JR |
192 | int new_transmit_hold_count) |
193 | OVS_EXCLUDED(rstp_mutex); | |
9efd308e DV |
194 | |
195 | /* Bridge getters */ | |
f025bcb7 JR |
196 | const char * rstp_get_name(const struct rstp *) |
197 | OVS_EXCLUDED(rstp_mutex); | |
198 | rstp_identifier rstp_get_root_id(const struct rstp *) | |
199 | OVS_EXCLUDED(rstp_mutex); | |
200 | rstp_identifier rstp_get_bridge_id(const struct rstp *) | |
201 | OVS_EXCLUDED(rstp_mutex); | |
202 | rstp_identifier rstp_get_designated_id(const struct rstp *) | |
203 | OVS_EXCLUDED(rstp_mutex); | |
204 | uint32_t rstp_get_root_path_cost(const struct rstp *) | |
205 | OVS_EXCLUDED(rstp_mutex); | |
206 | uint16_t rstp_get_designated_port_id(const struct rstp *) | |
207 | OVS_EXCLUDED(rstp_mutex); | |
208 | uint16_t rstp_get_bridge_port_id(const struct rstp *) | |
209 | OVS_EXCLUDED(rstp_mutex); | |
066f0ab4 | 210 | struct rstp_port * rstp_get_root_port(const struct rstp *) |
f025bcb7 JR |
211 | OVS_EXCLUDED(rstp_mutex); |
212 | rstp_identifier rstp_get_designated_root(const struct rstp *) | |
213 | OVS_EXCLUDED(rstp_mutex); | |
214 | bool rstp_is_root_bridge(const struct rstp *) | |
215 | OVS_EXCLUDED(rstp_mutex); | |
216 | ||
217 | /* RSTP ports */ | |
218 | struct rstp_port * rstp_add_port(struct rstp *) | |
219 | OVS_EXCLUDED(rstp_mutex); | |
220 | struct rstp_port *rstp_port_ref(const struct rstp_port *) | |
221 | OVS_EXCLUDED(rstp_mutex); | |
222 | void rstp_port_unref(struct rstp_port *) | |
223 | OVS_EXCLUDED(rstp_mutex); | |
224 | ||
225 | uint32_t rstp_convert_speed_to_cost(unsigned int speed); | |
8fb76a0b | 226 | |
f025bcb7 JR |
227 | void rstp_port_set(struct rstp_port *, uint16_t port_num, int priority, |
228 | uint32_t path_cost, bool is_admin_edge, bool is_auto_edge, | |
67e8c1ac | 229 | enum rstp_admin_point_to_point_mac_state admin_p2p_mac_state, |
8d2f8375 | 230 | bool admin_port_state, bool do_mcheck, void *aux, |
231 | const char *name) | |
f025bcb7 JR |
232 | OVS_EXCLUDED(rstp_mutex); |
233 | ||
234 | enum rstp_state rstp_port_get_state(const struct rstp_port *) | |
235 | OVS_EXCLUDED(rstp_mutex); | |
236 | ||
237 | void rstp_port_get_status(const struct rstp_port *, uint16_t *id, | |
238 | enum rstp_state *state, enum rstp_port_role *role, | |
9c64e6b8 JR |
239 | rstp_identifier *designated_bridge_id, |
240 | uint16_t *designated_port_id, | |
241 | uint32_t *designated_path_cost, int *tx_count, | |
242 | int *rx_count, int *error_count, int *uptime) | |
f025bcb7 JR |
243 | OVS_EXCLUDED(rstp_mutex); |
244 | ||
2372c146 JR |
245 | void * rstp_get_port_aux__(struct rstp *rstp, uint16_t port_number) |
246 | OVS_REQUIRES(rstp_mutex); | |
f025bcb7 JR |
247 | |
248 | \f | |
249 | /* Internal API for rstp-state-machines.c */ | |
250 | ||
251 | void rstp_port_set_state__(struct rstp_port *, enum rstp_state state) | |
252 | OVS_REQUIRES(rstp_mutex); | |
253 | ||
254 | \f | |
255 | /* Internal API for test-rstp.c */ | |
256 | ||
257 | struct rstp_port *rstp_get_port(struct rstp *rstp, uint16_t port_number) | |
258 | OVS_EXCLUDED(rstp_mutex); | |
259 | void reinitialize_port(struct rstp_port *p) | |
260 | OVS_EXCLUDED(rstp_mutex); | |
261 | ||
262 | int rstp_port_get_number(const struct rstp_port *) | |
263 | OVS_EXCLUDED(rstp_mutex); | |
264 | void rstp_port_set_priority(struct rstp_port *port, int priority) | |
265 | OVS_EXCLUDED(rstp_mutex); | |
266 | void rstp_port_set_aux(struct rstp_port *p, void *aux) | |
267 | OVS_EXCLUDED(rstp_mutex); | |
268 | void rstp_port_set_path_cost(struct rstp_port *port, uint32_t path_cost) | |
269 | OVS_EXCLUDED(rstp_mutex); | |
270 | void rstp_port_set_state(struct rstp_port *p, enum rstp_state state) | |
271 | OVS_EXCLUDED(rstp_mutex); | |
272 | ||
273 | \f | |
8fb76a0b JR |
274 | /* Inline functions. */ |
275 | /* Returns true if 'state' is one in which BPDU packets should be received | |
276 | * and transmitted on a port, false otherwise. | |
277 | */ | |
278 | static inline bool | |
279 | rstp_should_manage_bpdu(enum rstp_state state) | |
280 | { | |
281 | return (state == RSTP_DISCARDING || state == RSTP_LEARNING || | |
282 | state == RSTP_FORWARDING); | |
283 | } | |
284 | ||
285 | /* Returns true if 'state' is one in which packets received on a port should | |
286 | * be forwarded, false otherwise. | |
8fb76a0b JR |
287 | */ |
288 | static inline bool | |
289 | rstp_forward_in_state(enum rstp_state state) | |
290 | { | |
4b5f1996 | 291 | return (state == RSTP_FORWARDING); |
8fb76a0b JR |
292 | } |
293 | ||
294 | /* Returns true if 'state' is one in which MAC learning should be done on | |
295 | * packets received on a port, false otherwise. | |
4b5f1996 | 296 | */ |
8fb76a0b JR |
297 | static inline bool |
298 | rstp_learn_in_state(enum rstp_state state) | |
299 | { | |
4b5f1996 | 300 | return (state == RSTP_LEARNING || state == RSTP_FORWARDING); |
8fb76a0b JR |
301 | } |
302 | ||
9efd308e | 303 | #endif /* rstp.h */ |