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