/src/openvswitch/lib/rstp.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2011-2015 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) public interface (header |
19 | | * file). |
20 | | * |
21 | | * Authors: |
22 | | * Martino Fornasa <mf@fornasa.it> |
23 | | * Daniele Venturino <daniele.venturino@m3s.it> |
24 | | * Carlo Andreotti <c.andreotti@m3s.it> |
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 | | |
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 | | |
45 | | #define RSTP_MAX_PORTS 4095 |
46 | | |
47 | | struct dp_packet; |
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 2000 |
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 | | |
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 | | |
130 | | struct rstp; |
131 | | struct rstp_port; |
132 | | struct ofproto_rstp_settings; |
133 | | |
134 | | const char *rstp_state_name(enum rstp_state); |
135 | | const char *rstp_port_role_name(enum rstp_port_role); |
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); |
139 | | |
140 | | void rstp_init(void) |
141 | | OVS_EXCLUDED(rstp_mutex); |
142 | | |
143 | | struct rstp * rstp_create(const char *, rstp_identifier bridge_id, |
144 | | void (*send_bpdu)(struct dp_packet *, void *port_aux, |
145 | | void *rstp_aux), |
146 | | void *aux) |
147 | | OVS_EXCLUDED(rstp_mutex); |
148 | | |
149 | | struct rstp *rstp_ref(struct rstp *) |
150 | | OVS_EXCLUDED(rstp_mutex); |
151 | | void rstp_unref(struct rstp *) |
152 | | OVS_EXCLUDED(rstp_mutex); |
153 | | |
154 | | /* Functions used outside RSTP, to call functions defined in |
155 | | rstp-state-machines.h */ |
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); |
161 | | void *rstp_check_and_reset_fdb_flush(struct rstp *, struct rstp_port **) |
162 | | OVS_EXCLUDED(rstp_mutex); |
163 | | void *rstp_get_next_changed_port_aux(struct rstp *, struct rstp_port **) |
164 | | OVS_EXCLUDED(rstp_mutex); |
165 | | void rstp_port_set_mac_operational(struct rstp_port *, |
166 | | bool new_mac_operational) |
167 | | OVS_EXCLUDED(rstp_mutex); |
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); |
176 | | |
177 | | /* Bridge setters */ |
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); |
184 | | void rstp_set_bridge_force_protocol_version(struct rstp *, |
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); |
191 | | void rstp_set_bridge_transmit_hold_count(struct rstp *, |
192 | | int new_transmit_hold_count) |
193 | | OVS_EXCLUDED(rstp_mutex); |
194 | | |
195 | | /* Bridge getters */ |
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); |
210 | | struct rstp_port * rstp_get_root_port(const struct rstp *) |
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); |
226 | | |
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, |
229 | | enum rstp_admin_point_to_point_mac_state admin_p2p_mac_state, |
230 | | bool admin_port_state, bool do_mcheck, void *aux, |
231 | | const char *name) |
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, |
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) |
243 | | OVS_EXCLUDED(rstp_mutex); |
244 | | |
245 | | void * rstp_get_port_aux__(struct rstp *rstp, uint16_t port_number) |
246 | | OVS_REQUIRES(rstp_mutex); |
247 | | |
248 | | |
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 | | |
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 | | |
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 | 0 | { |
281 | 0 | return (state == RSTP_DISCARDING || state == RSTP_LEARNING || |
282 | 0 | state == RSTP_FORWARDING); |
283 | 0 | } |
284 | | |
285 | | /* Returns true if 'state' is one in which packets received on a port should |
286 | | * be forwarded, false otherwise. |
287 | | */ |
288 | | static inline bool |
289 | | rstp_forward_in_state(enum rstp_state state) |
290 | 0 | { |
291 | 0 | return (state == RSTP_FORWARDING); |
292 | 0 | } |
293 | | |
294 | | /* Returns true if 'state' is one in which MAC learning should be done on |
295 | | * packets received on a port, false otherwise. |
296 | | */ |
297 | | static inline bool |
298 | | rstp_learn_in_state(enum rstp_state state) |
299 | 0 | { |
300 | 0 | return (state == RSTP_LEARNING || state == RSTP_FORWARDING); |
301 | 0 | } |
302 | | |
303 | | #endif /* rstp.h */ |