]>
Commit | Line | Data |
---|---|---|
1e6d2d09 VD |
1 | /* |
2 | * mstp.h State machines from IEEE 802.1Q-2005 | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation; either version | |
7 | * 2 of the License, or (at your option) any later version. | |
8 | * | |
9 | * Authors: Vitalii Demianets <vitas@nppfactor.kiev.ua> | |
10 | */ | |
11 | ||
12 | #ifndef MSTP_H | |
13 | #define MSTP_H | |
14 | ||
15 | #include <stdlib.h> | |
16 | ||
17 | #include "bridge_ctl.h" | |
18 | #include "list.h" | |
19 | ||
20 | /* #define HMAC_MDS_TEST_FUNCTIONS */ | |
21 | ||
22 | /* Useful macro for counting number of elements in array */ | |
23 | #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) | |
24 | ||
25 | /* | |
26 | * assign() and cmp() macros that also do strict type-checking. See the | |
27 | * "unnecessary" pointer comparison. | |
28 | * NOTE: potential double-evaluation of the first argument in assign macro! | |
29 | * It is the price for type-safety ;) | |
30 | */ | |
31 | #define assign(x, y) ({ \ | |
32 | typeof(x) _assign1 = (x); \ | |
33 | typeof(y) _assign2 = (y); \ | |
34 | (void)(&_assign1 == &_assign2); \ | |
35 | (x) = _assign2; }) | |
36 | #define _ncmp(x, y) ({ \ | |
37 | typeof(x) _cmp1 = (x); \ | |
38 | typeof(y) _cmp2 = (y); \ | |
39 | (void)(&_cmp1 == &_cmp2); \ | |
40 | memcmp(&_cmp1, &_cmp2, sizeof(_cmp1)); }) | |
41 | #define cmp(x, _op, y) (_ncmp((x), (y)) _op 0) | |
42 | ||
1e6d2d09 VD |
43 | /* 13.7, Table 13-1 */ |
44 | #define HMAC_KEY {0x13, 0xAC, 0x06, 0xA6, 0x2E, 0x47, 0xFD, 0x51, \ | |
45 | 0xF9, 0x5D, 0x2B, 0xA2, 0x43, 0xCD, 0x03, 0x46} | |
46 | extern void hmac_md5(unsigned char * text, int text_len, unsigned char * key, | |
47 | int key_len, caddr_t digest); | |
48 | #ifdef HMAC_MDS_TEST_FUNCTIONS | |
49 | extern bool MD5TestSuite(void); | |
50 | #endif /* HMAC_MDS_TEST_FUNCTIONS */ | |
51 | ||
52 | #define MAX_PORT_NUMBER 4095 | |
53 | #define MAX_VID 4094 | |
54 | #define MAX_FID 4095 | |
55 | #define MAX_MSTID 4094 | |
56 | ||
57 | /* MAX_xxx_MSTIS: CIST not counted */ | |
58 | #define MAX_STANDARD_MSTIS 64 | |
59 | #define MAX_IMPLEMENTATION_MSTIS 63 | |
60 | ||
61 | /* 13.37.1 */ | |
62 | #define MAX_PATH_COST 200000000u | |
63 | ||
64 | typedef union | |
65 | { | |
66 | __u64 u; | |
67 | struct | |
68 | { | |
69 | __be16 priority; | |
70 | __u8 mac_address[ETH_ALEN]; | |
71 | } __attribute__((packed)) s; | |
72 | } bridge_identifier_t; | |
73 | ||
74 | typedef __be16 port_identifier_t; | |
75 | ||
76 | /* These macros work well for both PortID and BridgeID */ | |
77 | #define GET_PRIORITY_FROM_IDENTIFIER(id) (((__u8 *)(&(id)))[0] & 0xF0) | |
78 | #define SET_PRIORITY_IN_IDENTIFIER(pri, id) do{ \ | |
79 | __u8 *first_octet = (__u8 *)(&(id)); \ | |
80 | *first_octet &= 0x0F; \ | |
81 | *first_octet |= (pri) & 0xF0; \ | |
82 | }while(0) | |
83 | ||
84 | #define CONFIGURATION_NAME_LEN 32 | |
85 | #define CONFIGURATION_DIGEST_LEN 16 | |
86 | typedef union | |
87 | { | |
88 | __u8 a[1 + CONFIGURATION_NAME_LEN + 2 + CONFIGURATION_DIGEST_LEN]; | |
89 | struct | |
90 | { | |
91 | __u8 selector; /* always 0 */ | |
92 | __u8 configuration_name[CONFIGURATION_NAME_LEN]; | |
93 | __be16 revision_level; | |
94 | __u8 configuration_digest[CONFIGURATION_DIGEST_LEN]; | |
95 | } __attribute__((packed)) s; | |
96 | } __attribute__((packed)) mst_configuration_identifier_t; | |
97 | ||
98 | typedef struct | |
99 | { | |
100 | bridge_identifier_t RRootID; | |
101 | __be32 IntRootPathCost; | |
102 | bridge_identifier_t DesignatedBridgeID; | |
103 | port_identifier_t DesignatedPortID; | |
104 | /* not used for MSTIs, only for CIST */ | |
105 | bridge_identifier_t RootID; | |
106 | __be32 ExtRootPathCost; | |
107 | } port_priority_vector_t; | |
108 | ||
109 | /* 17.14 of 802.1D, Table 17-1 */ | |
110 | #define MIN_COMPAT_HELLO_TIME 1 | |
111 | ||
112 | typedef struct | |
113 | { | |
114 | __u8 remainingHops; | |
115 | /* not used for MSTIs, only for CIST */ | |
58665938 VD |
116 | __u8 Forward_Delay; |
117 | __u8 Max_Age; | |
118 | __u8 Message_Age; | |
119 | __u8 Hello_Time; | |
1e6d2d09 VD |
120 | } times_t; |
121 | ||
122 | typedef struct | |
123 | { | |
124 | /* see bpduFlagOffset_t enum for offsets of flag bits */ | |
125 | __u8 flags; | |
126 | bridge_identifier_t mstiRRootID; | |
127 | __be32 mstiIntRootPathCost; | |
128 | /* only bits 7..4, bits 3..0 are zero on Tx and ignored on Rx */ | |
129 | __u8 bridgeIdentifierPriority; | |
130 | /* only bits 7..4, bits 3..0 are zero on Tx and ignored on Rx */ | |
131 | __u8 portIdentifierPriority; | |
132 | __u8 remainingHops; | |
133 | } __attribute__((packed)) msti_configuration_message_t; | |
134 | ||
135 | typedef struct | |
136 | { | |
137 | /* always zero for the Spanning Tree BPDUs */ | |
138 | __be16 protocolIdentifier; | |
139 | /* protoSTP for the Config and TCN | |
140 | * protoRSTP for the RST | |
141 | * protoMSTP for the MST | |
142 | * (see protocol_version_t enum) */ | |
143 | __u8 protocolVersion; | |
144 | /* values are defined in bpduType_t enum */ | |
145 | __u8 bpduType; | |
146 | /* TCN BPDU ends here */ | |
147 | /* see bpduFlagOffset_t enum for offsets of flag bits */ | |
148 | __u8 flags; | |
149 | bridge_identifier_t cistRootID; | |
150 | __be32 cistExtRootPathCost; | |
151 | bridge_identifier_t cistRRootID; | |
152 | port_identifier_t cistPortID; | |
58665938 VD |
153 | __u8 MessageAge[2]; |
154 | __u8 MaxAge[2]; | |
155 | __u8 HelloTime[2]; | |
156 | __u8 ForwardDelay[2]; | |
1e6d2d09 VD |
157 | /* Config BPDU ends here */ |
158 | __u8 version1_len; /* always zero */ | |
159 | /* RST BPDU ends here */ | |
160 | __be16 version3_len; | |
161 | mst_configuration_identifier_t mstConfigurationIdentifier; | |
162 | __be32 cistIntRootPathCost; | |
163 | bridge_identifier_t cistBridgeID; | |
164 | __u8 cistRemainingHops; | |
165 | msti_configuration_message_t mstConfiguration[MAX_STANDARD_MSTIS]; | |
166 | } __attribute__((packed)) bpdu_t; | |
167 | ||
168 | #define TCN_BPDU_SIZE offsetof(bpdu_t, flags) | |
169 | #define CONFIG_BPDU_SIZE offsetof(bpdu_t, version1_len) | |
170 | #define RST_BPDU_SIZE offsetof(bpdu_t, version3_len) | |
171 | #define MST_BPDU_SIZE_WO_MSTI_MSGS offsetof(bpdu_t, mstConfiguration) | |
172 | #define MST_BPDU_VER3LEN_WO_MSTI_MSGS (MST_BPDU_SIZE_WO_MSTI_MSGS \ | |
173 | - offsetof(bpdu_t, mstConfigurationIdentifier)) | |
174 | ||
175 | typedef enum | |
176 | { | |
177 | OtherInfo, | |
178 | SuperiorDesignatedInfo, | |
179 | RepeatedDesignatedInfo, | |
180 | InferiorDesignatedInfo, | |
181 | InferiorRootAlternateInfo | |
182 | } port_info_t; | |
183 | ||
184 | typedef enum | |
185 | { | |
5453a511 VD |
186 | ioDisabled, |
187 | ioMine, | |
188 | ioAged, | |
189 | ioReceived | |
1e6d2d09 VD |
190 | } port_info_origin_t; |
191 | ||
192 | typedef enum | |
193 | { | |
5453a511 VD |
194 | roleDisabled, |
195 | roleRoot, | |
196 | roleDesignated, | |
197 | roleAlternate, | |
198 | roleBackup, | |
199 | roleMaster | |
1e6d2d09 VD |
200 | } port_role_t; |
201 | ||
202 | typedef enum | |
203 | { | |
204 | encodedRoleMaster = 0, | |
205 | encodedRoleAlternateBackup = 1, | |
206 | encodedRoleRoot = 2, | |
207 | encodedRoleDesignated = 3 | |
208 | } port_encoded_role_t; | |
209 | ||
210 | typedef enum | |
211 | { | |
5453a511 VD |
212 | protoSTP = 0, |
213 | protoRSTP = 2, | |
214 | protoMSTP = 3 | |
1e6d2d09 VD |
215 | } protocol_version_t; |
216 | ||
217 | typedef enum | |
218 | { | |
219 | bpduTypeConfig = 0, | |
220 | bpduTypeRST = 2, | |
221 | bpduTypeTCN = 128 | |
222 | } bpduType_t; | |
223 | ||
224 | typedef enum | |
225 | { | |
226 | offsetTc = 0, | |
227 | offsetProposal = 1, | |
228 | offsetRole = 2, /* actually, role is coded in two-bit field */ | |
229 | offsetRole1 = 3, /* second bit of two-bit role field */ | |
230 | offsetLearnig = 4, | |
231 | offsetForwarding = 5, | |
232 | offsetAgreement = 6, | |
233 | offsetTcAck = 7 | |
234 | /* in MSTI Configuration Message flags bit7 is used for Master flag */ | |
235 | #define offsetMaster offsetTcAck | |
236 | } bpduFlagOffset_t; | |
237 | ||
238 | #define BPDU_FLAGS_ROLE_SET(role) (((role) & 3) << offsetRole) | |
239 | #define BPDU_FLAGS_ROLE_GET(flags) (((flags) >> offsetRole) & 3) | |
240 | ||
241 | typedef enum | |
242 | { | |
243 | p2pAuto, | |
244 | p2pForceTrue, | |
245 | p2pForceFalse | |
246 | } | |
247 | admin_p2p_t; | |
248 | ||
1e6d2d09 VD |
249 | /* 13.28 Port Receive state machine */ |
250 | typedef enum | |
251 | { | |
252 | PRSM_DISCARD, | |
253 | PRSM_RECEIVE | |
254 | } PRSM_states_t; | |
255 | ||
256 | /* 13.29 Port Protocol Migration state machine */ | |
257 | typedef enum | |
258 | { | |
259 | PPMSM_CHECKING_RSTP, | |
260 | PPMSM_SELECTING_STP, | |
261 | PPMSM_SENSING | |
262 | } PPMSM_states_t; | |
263 | ||
264 | /* 13.30 Bridge Detection state machine */ | |
265 | typedef enum | |
266 | { | |
267 | BDSM_EDGE, | |
268 | BDSM_NOT_EDGE | |
269 | } BDSM_states_t; | |
270 | ||
271 | /* 13.31 Port Transmit state machine */ | |
272 | typedef enum | |
273 | { | |
274 | PTSM_TRANSMIT_INIT, | |
275 | PTSM_TRANSMIT_CONFIG, | |
276 | PTSM_TRANSMIT_TCN, | |
277 | PTSM_TRANSMIT_RSTP, | |
278 | PTSM_TRANSMIT_PERIODIC, | |
279 | PTSM_IDLE | |
280 | } PTSM_states_t; | |
281 | ||
282 | /* 13.32 Port Information state machine */ | |
283 | /* #define PISM_ENABLE_LOG */ | |
284 | typedef enum | |
285 | { | |
286 | PISM_DISABLED, | |
287 | PISM_AGED, | |
288 | PISM_UPDATE, | |
289 | PISM_SUPERIOR_DESIGNATED, | |
290 | PISM_REPEATED_DESIGNATED, | |
291 | PISM_INFERIOR_DESIGNATED, | |
292 | PISM_NOT_DESIGNATED, | |
293 | PISM_OTHER, | |
294 | PISM_CURRENT, | |
295 | PISM_RECEIVE | |
296 | } PISM_states_t; | |
297 | ||
298 | /* 13.33 Port Role Selection state machine */ | |
299 | typedef enum | |
300 | { | |
301 | PRSSM_INIT_TREE, | |
302 | PRSSM_ROLE_SELECTION | |
303 | } PRSSM_states_t; | |
304 | ||
305 | /* 13.34 Port Role Transitions state machine */ | |
306 | /* #define PRTSM_ENABLE_LOG */ | |
307 | typedef enum | |
308 | { | |
309 | /* Disabled Port role transitions */ | |
310 | PRTSM_INIT_PORT, | |
311 | PRTSM_DISABLE_PORT, | |
312 | PRTSM_DISABLED_PORT, | |
313 | /* MasterPort role transitions */ | |
314 | PRTSM_MASTER_PROPOSED, | |
315 | PRTSM_MASTER_AGREED, | |
316 | PRTSM_MASTER_SYNCED, | |
317 | PRTSM_MASTER_RETIRED, | |
318 | PRTSM_MASTER_FORWARD, | |
319 | PRTSM_MASTER_LEARN, | |
320 | PRTSM_MASTER_DISCARD, | |
321 | PRTSM_MASTER_PORT, | |
322 | /* RootPort role transitions */ | |
323 | PRTSM_ROOT_PROPOSED, | |
324 | PRTSM_ROOT_AGREED, | |
325 | PRTSM_ROOT_SYNCED, | |
326 | PRTSM_REROOT, | |
327 | PRTSM_ROOT_FORWARD, | |
328 | PRTSM_ROOT_LEARN, | |
329 | PRTSM_REROOTED, | |
330 | PRTSM_ROOT_PORT, | |
331 | /* DesignatedPort role transitions */ | |
332 | PRTSM_DESIGNATED_PROPOSE, | |
333 | PRTSM_DESIGNATED_AGREED, | |
334 | PRTSM_DESIGNATED_SYNCED, | |
335 | PRTSM_DESIGNATED_RETIRED, | |
336 | PRTSM_DESIGNATED_FORWARD, | |
337 | PRTSM_DESIGNATED_LEARN, | |
338 | PRTSM_DESIGNATED_DISCARD, | |
339 | PRTSM_DESIGNATED_PORT, | |
340 | /* AlternatePort and BackupPort role transitions */ | |
341 | PRTSM_BLOCK_PORT, | |
342 | PRTSM_BACKUP_PORT, | |
343 | PRTSM_ALTERNATE_PROPOSED, | |
344 | PRTSM_ALTERNATE_AGREED, | |
345 | PRTSM_ALTERNATE_PORT | |
346 | } PRTSM_states_t; | |
347 | ||
348 | /* 13.35 Port State Transition state machine */ | |
349 | typedef enum | |
350 | { | |
351 | PSTSM_DISCARDING, | |
352 | PSTSM_LEARNING, | |
353 | PSTSM_FORWARDING | |
354 | } PSTSM_states_t; | |
355 | ||
356 | /* 13.36 Topology Change state machine */ | |
357 | typedef enum | |
358 | { | |
359 | TCSM_INACTIVE, | |
360 | TCSM_LEARNING, | |
361 | TCSM_DETECTED, | |
362 | TCSM_NOTIFIED_TCN, | |
363 | TCSM_NOTIFIED_TC, | |
364 | TCSM_PROPAGATING, | |
365 | TCSM_ACKNOWLEDGED, | |
366 | TCSM_ACTIVE | |
367 | } TCSM_states_t; | |
368 | ||
369 | /* | |
370 | * Following standard-defined variables are not defined as variables. | |
371 | * Their functionality is implemented indirectly by other means: | |
372 | * - BEGIN, tick, ageingTime. | |
373 | */ | |
374 | ||
375 | typedef struct | |
376 | { | |
377 | struct list_head list; /* anchor in global list of bridges */ | |
378 | ||
379 | /* List of all ports */ | |
380 | struct list_head ports; | |
381 | /* List of all tree instances, first in list (trees.next) is CIST */ | |
382 | struct list_head trees; | |
383 | #define GET_CIST_TREE(br) list_entry((br)->trees.next, tree_t, bridge_list) | |
384 | ||
385 | bool bridgeEnabled; | |
386 | ||
387 | /* Per-bridge configuration parameters */ | |
388 | mst_configuration_identifier_t MstConfigId; /* 13.24.b */ | |
1e6d2d09 | 389 | protocol_version_t ForceProtocolVersion; /* 13.22.e */ |
58665938 VD |
390 | __u8 MaxHops; /* 13.22.o */ |
391 | __u8 Forward_Delay; /* 13.22.f */ | |
392 | __u8 Max_Age; /* 13.22.i */ | |
1e6d2d09 VD |
393 | unsigned int Transmit_Hold_Count; /* 13.22.g */ |
394 | unsigned int Migrate_Time; /* 13.22.h */ | |
c109fcb6 | 395 | unsigned int Ageing_Time; /* 8.8.3 */ |
1e6d2d09 VD |
396 | unsigned int rapidAgeingWhile; |
397 | ||
398 | __u16 vid2fid[MAX_VID + 1]; | |
399 | __be16 fid2mstid[MAX_FID + 1]; | |
400 | ||
401 | /* not in standard */ | |
402 | unsigned int uptime; | |
403 | ||
404 | sysdep_br_data_t sysdeps; | |
405 | } bridge_t; | |
406 | ||
407 | typedef struct | |
408 | { | |
409 | struct list_head bridge_list; /* anchor in bridge's list of trees */ | |
410 | bridge_t * bridge; | |
411 | __be16 MSTID; /* 0 == CIST */ | |
412 | ||
413 | /* List of the per-port data structures for this tree instance */ | |
414 | struct list_head ports; | |
415 | ||
416 | /* 13.23.(c,f,g) Per-bridge per-tree variables */ | |
417 | bridge_identifier_t BridgeIdentifier; | |
418 | port_identifier_t rootPortId; | |
419 | port_priority_vector_t rootPriority; | |
420 | ||
421 | /* 13.23.d This is totally calculated from BridgeIdentifier */ | |
422 | port_priority_vector_t BridgePriority; | |
423 | ||
424 | /* 13.23.e Some waste of space here, as MSTIs only use | |
425 | * remainingHops member of the struct times_t, | |
426 | * but saves extra checks and improves readability */ | |
427 | times_t BridgeTimes, rootTimes; | |
428 | ||
429 | /* 12.8.1.1.3.(b,c,d) */ | |
430 | unsigned int time_since_topology_change; | |
431 | unsigned int topology_change_count; | |
432 | bool topology_change; | |
433 | ||
434 | /* State machines */ | |
435 | PRSSM_states_t PRSSM_state; | |
436 | ||
437 | } tree_t; | |
438 | ||
439 | typedef struct | |
440 | { | |
441 | struct list_head br_list; /* anchor in bridge's list of ports */ | |
442 | bridge_t * bridge; | |
443 | __be16 port_number; | |
444 | ||
445 | /* List of all tree instances, first in list (trees.next) is CIST. | |
446 | * List is sorted by MSTID (by insertion procedure MSTP_IN_create_msti). | |
447 | */ | |
448 | struct list_head trees; | |
449 | #define GET_CIST_PTP_FROM_PORT(prt) \ | |
450 | list_entry((prt)->trees.next, per_tree_port_t, port_list) | |
451 | ||
452 | /* 13.21.(a,b,c) Per-port timers */ | |
453 | unsigned int mdelayWhile, helloWhen, edgeDelayWhile; | |
454 | ||
455 | /* 13.24.(b,c,e,f,g,j,k,l,m,n,o,p,q,r,aw) Per-port variables */ | |
456 | unsigned int txCount; | |
457 | bool operEdge, portEnabled, infoInternal, rcvdInternal; | |
458 | bool mcheck, rcvdBpdu, rcvdRSTP, rcvdSTP, rcvdTcAck, rcvdTcn, sendRSTP; | |
459 | bool tcAck, newInfo, newInfoMsti; | |
460 | ||
461 | /* 6.4.3 */ | |
462 | bool operPointToPointMAC; | |
463 | ||
464 | /* Per-port configuration parameters */ | |
465 | bool restrictedRole, restrictedTcn; /* 13.24.(h,i) */ | |
466 | __u32 ExternalPortPathCost; /* 13.22.p */ | |
467 | __u32 AdminExternalPortPathCost; /* 0 = calculate from speed */ | |
468 | admin_p2p_t AdminP2P; /* 6.4.3 */ | |
469 | bool AdminEdgePort; /* 13.22.k */ | |
470 | bool AutoEdge; /* 13.22.m */ | |
471 | ||
472 | /* State machines */ | |
473 | PRSM_states_t PRSM_state; | |
474 | PPMSM_states_t PPMSM_state; | |
475 | BDSM_states_t BDSM_state; | |
476 | PTSM_states_t PTSM_state; | |
477 | ||
478 | /* Copy of the received BPDU */ | |
479 | bpdu_t rcvdBpduData; | |
480 | int rcvdBpduNumOfMstis; | |
481 | ||
482 | sysdep_if_data_t sysdeps; | |
483 | } port_t; | |
484 | ||
485 | typedef struct | |
486 | { | |
487 | struct list_head port_list; /* anchor in port's list of trees */ | |
488 | struct list_head tree_list; /* anchor in tree's list of per-port data */ | |
489 | port_t *port; | |
490 | tree_t *tree; | |
491 | __be16 MSTID; /* 0 == CIST */ | |
492 | ||
493 | int state; /* BR_STATE_xxx */ | |
494 | ||
495 | /* 13.21.(d,e,f,g,h) Per-port per-tree timers */ | |
496 | unsigned int fdWhile, rrWhile, rbWhile, tcWhile, rcvdInfoWhile; | |
497 | ||
498 | /* 13.24.(s,t,u,v,w,x,y,z,aa,ab,ac,ad,ae,af,ag,ai,aj,ak,ap,as,at,au,av) | |
499 | * Per-port per-tree variables */ | |
500 | bool agree, agreed, disputed, forward, forwarding, learn, learning; | |
501 | port_info_t rcvdInfo; | |
502 | port_info_origin_t infoIs; | |
503 | bool proposed, proposing, rcvdMsg, rcvdTc, reRoot, reselect, selected; | |
504 | bool fdbFlush, tcProp, updtInfo, sync, synced; | |
505 | port_identifier_t portId; | |
506 | port_role_t role, selectedRole; | |
507 | ||
508 | /* 13.24.(al,an,aq) Some waste of space here, as MSTIs don't use | |
509 | * RootID and ExtRootPathCost members of the struct port_priority_vector_t, | |
510 | * but saves extra checks and improves readability */ | |
511 | port_priority_vector_t designatedPriority, msgPriority, portPriority; | |
512 | ||
513 | /* 13.24.(am,ao,ar) Some waste of space here, as MSTIs only use | |
514 | * remainingHops member of the struct times_t, | |
515 | * but saves extra checks and improves readability */ | |
516 | times_t designatedTimes, msgTimes, portTimes; | |
517 | ||
518 | /* 13.24.(ax,ay) Per-port per-MSTI variables, not applicable to CIST */ | |
519 | bool master, mastered; | |
520 | ||
521 | /* Per-port per-tree configuration parameters */ | |
522 | __u32 InternalPortPathCost; /* 13.22.q */ | |
523 | __u32 AdminInternalPortPathCost; /* 0 = calculate from speed */ | |
524 | ||
525 | /* not in standard, used for calculation of port uptime */ | |
526 | unsigned int start_time; | |
527 | ||
528 | /* State machines */ | |
529 | PISM_states_t PISM_state; | |
530 | PRTSM_states_t PRTSM_state; | |
531 | PSTSM_states_t PSTSM_state; | |
532 | TCSM_states_t TCSM_state; | |
533 | ||
5323b89e VD |
534 | /* Auxiliary flag, helps preventing infinite recursion */ |
535 | bool calledFromFlushRoutine; | |
536 | ||
1e6d2d09 VD |
537 | /* Pointer to the corresponding MSTI Configuration Message |
538 | * in the port->rcvdBpduData */ | |
539 | msti_configuration_message_t *rcvdMstiConfig; | |
540 | } per_tree_port_t; | |
541 | ||
542 | /* External events (inputs) */ | |
543 | bool MSTP_IN_bridge_create(bridge_t *br, __u8 *macaddr); | |
544 | bool MSTP_IN_port_create_and_add_tail(port_t *prt, __u16 portno); | |
545 | void MSTP_IN_delete_port(port_t *prt); | |
546 | void MSTP_IN_delete_bridge(bridge_t *br); | |
547 | void MSTP_IN_set_bridge_address(bridge_t *br, __u8 *macaddr); | |
548 | void MSTP_IN_set_bridge_enable(bridge_t *br, bool up); | |
549 | void MSTP_IN_set_port_enable(port_t *prt, bool up, int speed, int duplex); | |
550 | void MSTP_IN_one_second(bridge_t *br); | |
551 | void MSTP_IN_all_fids_flushed(per_tree_port_t *ptp); | |
552 | void MSTP_IN_rx_bpdu(port_t *prt, bpdu_t *bpdu, int size); | |
553 | ||
554 | bool MSTP_IN_set_vid2fid(bridge_t *br, __u16 vid, __u16 fid); | |
555 | bool MSTP_IN_set_all_vids2fids(bridge_t *br, __u16 *vids2fids); | |
556 | bool MSTP_IN_set_fid2mstid(bridge_t *br, __u16 fid, __u16 mstid); | |
557 | bool MSTP_IN_set_all_fids2mstids(bridge_t *br, __u16 *fids2mstids); | |
558 | bool MSTP_IN_get_mstilist(bridge_t *br, int *num_mstis, __u16 *mstids); | |
559 | bool MSTP_IN_create_msti(bridge_t *br, __u16 mstid); | |
560 | bool MSTP_IN_delete_msti(bridge_t *br, __u16 mstid); | |
561 | void MSTP_IN_set_mst_config_id(bridge_t *br, __u16 revision, __u8 *name); | |
562 | ||
563 | /* External actions (outputs) */ | |
564 | void MSTP_OUT_set_state(per_tree_port_t *ptp, int new_state); | |
565 | void MSTP_OUT_flush_all_fids(per_tree_port_t *ptp); | |
c109fcb6 | 566 | void MSTP_OUT_set_ageing_time(bridge_t *br, unsigned int ageingTime); |
1e6d2d09 VD |
567 | void MSTP_OUT_tx_bpdu(port_t *prt, bpdu_t *bpdu, int size); |
568 | ||
569 | /* Structures for communicating with user */ | |
570 | /* 12.8.1.1 Read CIST Bridge Protocol Parameters */ | |
571 | typedef struct | |
572 | { | |
573 | bridge_identifier_t bridge_id; | |
574 | unsigned int time_since_topology_change; | |
575 | unsigned int topology_change_count; | |
576 | bool topology_change; | |
577 | bridge_identifier_t designated_root; | |
578 | unsigned int root_path_cost; | |
579 | port_identifier_t root_port_id; | |
58665938 VD |
580 | __u8 root_max_age; |
581 | __u8 root_forward_delay; | |
582 | __u8 bridge_max_age; | |
583 | __u8 bridge_forward_delay; | |
1e6d2d09 VD |
584 | unsigned int tx_hold_count; |
585 | protocol_version_t protocol_version; | |
586 | bridge_identifier_t regional_root; | |
587 | unsigned int internal_path_cost; | |
588 | bool enabled; /* not in standard */ | |
589 | __u8 max_hops; | |
590 | } CIST_BridgeStatus; | |
591 | ||
592 | void MSTP_IN_get_cist_bridge_status(bridge_t *br, CIST_BridgeStatus *status); | |
593 | ||
594 | /* 12.8.1.2 Read MSTI Bridge Protocol Parameters */ | |
595 | typedef struct | |
596 | { | |
597 | bridge_identifier_t bridge_id; | |
598 | unsigned int time_since_topology_change; | |
599 | unsigned int topology_change_count; | |
600 | bool topology_change; | |
601 | bridge_identifier_t regional_root; | |
602 | unsigned int internal_path_cost; | |
603 | port_identifier_t root_port_id; | |
604 | } MSTI_BridgeStatus; | |
605 | ||
606 | void MSTP_IN_get_msti_bridge_status(tree_t *tree, MSTI_BridgeStatus *status); | |
607 | ||
608 | /* 12.8.1.3 Set CIST Bridge Protocol Parameters */ | |
609 | typedef struct | |
610 | { | |
58665938 | 611 | __u8 bridge_max_age; |
1e6d2d09 VD |
612 | bool set_bridge_max_age; |
613 | ||
58665938 | 614 | __u8 bridge_forward_delay; |
1e6d2d09 VD |
615 | bool set_bridge_forward_delay; |
616 | ||
617 | /* Superseded by MSTP_IN_set_msti_bridge_config for the CIST. | |
618 | * __u8 bridge_priority; | |
619 | * bool set_bridge_priority; */ | |
620 | ||
621 | protocol_version_t protocol_version; | |
622 | bool set_protocol_version; | |
623 | ||
624 | unsigned int tx_hold_count; | |
625 | bool set_tx_hold_count; | |
626 | ||
627 | __u8 max_hops; | |
628 | bool set_max_hops; | |
629 | } CIST_BridgeConfig; | |
630 | ||
631 | int MSTP_IN_set_cist_bridge_config(bridge_t *br, CIST_BridgeConfig *cfg); | |
632 | ||
633 | /* 12.8.1.4 Set MSTI Bridge Protocol Parameters */ | |
634 | /* No need in special structure for single parameter Bridge Priority */ | |
635 | ||
636 | int MSTP_IN_set_msti_bridge_config(tree_t *tree, __u8 bridge_priority); | |
637 | ||
638 | /* 12.8.2.1 Read CIST Port Parameters */ | |
639 | typedef struct | |
640 | { | |
641 | unsigned int uptime; | |
642 | int state; /* BR_STATE_xxx */ | |
643 | port_identifier_t port_id; | |
644 | __u32 admin_external_port_path_cost; /* not in standard. 0 = auto */ | |
645 | __u32 external_port_path_cost; | |
646 | bridge_identifier_t designated_root; /* from portPriority */ | |
647 | __u32 designated_external_cost; /* from portPriority */ | |
648 | bridge_identifier_t designated_bridge; /* from portPriority */ | |
649 | port_identifier_t designated_port; /* from portPriority */ | |
650 | bool tc_ack; /* tcAck */ | |
58665938 | 651 | __u8 port_hello_time; /* from portTimes */ |
1e6d2d09 VD |
652 | bool admin_edge_port; |
653 | bool auto_edge_port; /* not in standard */ | |
654 | bool oper_edge_port; | |
655 | /* 802.1Q-2005 wants here MAC_Enabled & MAC_Operational. We don't know | |
656 | * neither of these. Return portEnabled and feel happy. */ | |
657 | bool enabled; | |
658 | admin_p2p_t admin_p2p; | |
659 | bool oper_p2p; | |
660 | bool restricted_role; | |
661 | bool restricted_tcn; | |
662 | port_role_t role; | |
663 | bool disputed; | |
664 | bridge_identifier_t designated_regional_root; /* from portPriority */ | |
665 | __u32 designated_internal_cost; /* from portPriority */ | |
666 | __u32 admin_internal_port_path_cost; /* not in standard. 0 = auto */ | |
667 | __u32 internal_port_path_cost; /* not in standard */ | |
668 | } CIST_PortStatus; | |
669 | ||
670 | void MSTP_IN_get_cist_port_status(port_t *prt, CIST_PortStatus *status); | |
671 | ||
672 | /* 12.8.2.2 Read MSTI Port Parameters */ | |
673 | typedef struct | |
674 | { | |
675 | unsigned int uptime; | |
676 | int state; /* BR_STATE_xxx */ | |
677 | port_identifier_t port_id; | |
678 | __u32 admin_internal_port_path_cost; /* not in standard. 0 = auto */ | |
679 | __u32 internal_port_path_cost; | |
680 | bridge_identifier_t designated_regional_root; /* from portPriority */ | |
681 | __u32 designated_internal_cost; /* from portPriority */ | |
682 | bridge_identifier_t designated_bridge; /* from portPriority */ | |
683 | port_identifier_t designated_port; /* from portPriority */ | |
684 | port_role_t role; | |
685 | bool disputed; | |
686 | } MSTI_PortStatus; | |
687 | ||
688 | void MSTP_IN_get_msti_port_status(per_tree_port_t *ptp, | |
689 | MSTI_PortStatus *status); | |
690 | ||
691 | /* 12.8.2.3 Set CIST port parameters */ | |
692 | typedef struct | |
693 | { | |
694 | __u32 admin_external_port_path_cost; /* not in standard. 0 = auto */ | |
695 | bool set_admin_external_port_path_cost; | |
696 | ||
697 | /* Superseded by MSTP_IN_set_msti_port_config for the CIST. | |
698 | * __u32 admin_internal_port_path_cost; | |
699 | * bool set_admin_internal_port_path_cost; | |
700 | * | |
701 | * __u8 port_priority; | |
702 | * bool set_port_priority; | |
703 | */ | |
704 | ||
705 | bool admin_edge_port; | |
706 | bool set_admin_edge_port; | |
707 | ||
708 | bool auto_edge_port; /* not in standard */ | |
709 | bool set_auto_edge_port; | |
710 | ||
711 | admin_p2p_t admin_p2p; | |
712 | bool set_admin_p2p; | |
713 | ||
714 | bool restricted_role; | |
715 | bool set_restricted_role; | |
716 | ||
717 | bool restricted_tcn; | |
718 | bool set_restricted_tcn; | |
719 | } CIST_PortConfig; | |
720 | ||
721 | int MSTP_IN_set_cist_port_config(port_t *prt, CIST_PortConfig *cfg); | |
722 | ||
723 | /* 12.8.2.4 Set MSTI port parameters */ | |
724 | typedef struct | |
725 | { | |
726 | __u32 admin_internal_port_path_cost; /* 0 = auto */ | |
727 | bool set_admin_internal_port_path_cost; | |
728 | ||
729 | __u8 port_priority; | |
730 | bool set_port_priority; | |
731 | } MSTI_PortConfig; | |
732 | ||
733 | int MSTP_IN_set_msti_port_config(per_tree_port_t *ptp, MSTI_PortConfig *cfg); | |
734 | ||
735 | /* 12.8.2.5 Force BPDU Migration Check */ | |
736 | int MSTP_IN_port_mcheck(port_t *prt); | |
737 | ||
738 | #endif /* MSTP_H */ |