]> git.ipfire.org Git - people/ms/rstp.git/blob - CHANGES_TO_RSTPLIB
RSTP testing - PATCH: source MAC address of BPDU
[people/ms/rstp.git] / CHANGES_TO_RSTPLIB
1 Some changes have been made to RSTPLIB version rsttplib.1.1.0.2 for use in this
2 program. The changes are given in the following diff.
3 The changes fall into 3 categories:
4
5 1. Changes to support dynamic addition and deletion of bridge ports.
6 2. Changes to support multiple bridges.
7 3. Fixes to protocol part based on 802.1w conformance testing results.
8
9
10 diff -Naur rstplib.1.1.02/base.h rstplib/base.h
11 --- rstplib.1.1.02/base.h 2002-01-20 00:33:22.000000000 -0800
12 +++ rstplib/base.h 2006-10-26 13:43:15.000000000 -0700
13 @@ -75,6 +75,7 @@
14 CHOOSE(STP_Imlicite_Instance_Create_Failed), \
15 CHOOSE(STP_Small_Bridge_Priority), \
16 CHOOSE(STP_Large_Bridge_Priority), \
17 + CHOOSE(STP_Bridge_Priority_Not_A_Multiple_Of_4096), \
18 CHOOSE(STP_Small_Hello_Time), \
19 CHOOSE(STP_Large_Hello_Time), \
20 CHOOSE(STP_Small_Max_Age), \
21 @@ -83,6 +84,10 @@
22 CHOOSE(STP_Large_Forward_Delay), \
23 CHOOSE(STP_Forward_Delay_And_Max_Age_Are_Inconsistent),\
24 CHOOSE(STP_Hello_Time_And_Max_Age_Are_Inconsistent), \
25 + CHOOSE(STP_Small_Port_Priority), \
26 + CHOOSE(STP_Large_Port_Priority), \
27 + CHOOSE(STP_Port_Priority_Not_A_Multiple_Of_16), \
28 + CHOOSE(STP_Large_Port_PCost), \
29 CHOOSE(STP_Vlan_Had_Not_Yet_Been_Created), \
30 CHOOSE(STP_Port_Is_Absent_In_The_Vlan), \
31 CHOOSE(STP_Big_len8023_Format), \
32 @@ -176,11 +181,11 @@
33
34 /* for debug trace messages */
35
36 -#ifdef __LINUX__
37 +#ifdef __LINUX__USE_PRINTF_FOR_STRACE
38 extern char* sprint_time_stump (void);
39 #define stp_trace(F, B...) printf("%s:" F "\n", sprint_time_stump(), ##B)
40 #else
41 -extern ULONG stp_trace (const char* fmt, ...);
42 +extern void stp_trace (const char* fmt, ...);
43 #endif
44
45 #endif /* _STP_BASE_H__ */
46 diff -Naur rstplib.1.1.02/pcost.c rstplib/pcost.c
47 --- rstplib.1.1.02/pcost.c 2002-01-20 00:34:09.000000000 -0800
48 +++ rstplib/pcost.c 2006-10-20 16:04:16.000000000 -0700
49 @@ -70,8 +70,10 @@
50 }
51
52 static void
53 -updPortPathCost (STATE_MACH_T *this)
54 +updPortPathCost (PORT_T *port)
55 {
56 + port->reselect = True;
57 + port->selected = False;
58 }
59
60 void
61 @@ -97,7 +99,7 @@
62 port->usedSpeed = -1;
63 break;
64 case STABLE:
65 - updPortPathCost (this);
66 + updPortPathCost (port);
67 break;
68 }
69 }
70 diff -Naur rstplib.1.1.02/port.c rstplib/port.c
71 --- rstplib.1.1.02/port.c 2002-01-20 00:34:10.000000000 -0800
72 +++ rstplib/port.c 2006-10-20 16:04:16.000000000 -0700
73 @@ -139,10 +139,10 @@
74 this->port_id,
75 this->port_id);
76 STP_copy_times (&this->designTimes, &stpm->rootTimes);
77 + this->fdWhile = 0;
78 }
79
80 /* reset timers */
81 - this->fdWhile =
82 this->helloWhen =
83 this->mdelayWhile =
84 this->rbWhile =
85 diff -Naur rstplib.1.1.02/portinfo.c rstplib/portinfo.c
86 --- rstplib.1.1.02/portinfo.c 2002-01-20 00:34:10.000000000 -0800
87 +++ rstplib/portinfo.c 2006-10-20 16:04:16.000000000 -0700
88 @@ -75,6 +75,12 @@
89
90 if (BPDU_RSTP == port->msgBpduType) {
91 port->msgPortRole = (port->msgFlags & PORT_ROLE_MASK) >> PORT_ROLE_OFFS;
92 +#ifndef ORIG
93 + if (RSTP_PORT_ROLE_UNKN == port->msgPortRole) {
94 + port->msgBpduVersion = FORCE_STP_COMPAT;
95 + port->msgBpduType = BPDU_CONFIG_TYPE;
96 + }
97 +#endif
98 }
99
100 if (RSTP_PORT_ROLE_DESGN == port->msgPortRole ||
101 @@ -109,10 +115,14 @@
102 }
103 }
104
105 - if (RSTP_PORT_ROLE_ROOT == port->msgBpduType &&
106 + if (RSTP_PORT_ROLE_ROOT == port->msgPortRole &&
107 port->operPointToPointMac &&
108 + ! STP_VECT_compare_bridge_id (&port->msgPrio.root_bridge,
109 + &port->portPrio.root_bridge) &&
110 + port->msgPrio.root_path_cost == port->portPrio.root_path_cost &&
111 ! STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
112 &port->portPrio.design_bridge) &&
113 + port->msgPrio.design_port == port->portPrio.design_port &&
114 AGREEMENT_BIT & port->msgFlags) {
115 #ifdef STP_DBG
116 if (this->debug) {
117 diff -Naur rstplib.1.1.02/stp_in.c rstplib/stp_in.c
118 --- rstplib.1.1.02/stp_in.c 2002-01-20 00:34:13.000000000 -0800
119 +++ rstplib/stp_in.c 2006-10-20 16:04:16.000000000 -0700
120 @@ -170,6 +170,11 @@
121 return STP_Large_Bridge_Priority;
122 }
123
124 + if (uid_cfg->bridge_priority & ~MASK_BR_PRIO) {
125 + stp_trace ("%d bridge_priority must be a multiple of 4096", (int) uid_cfg->bridge_priority);
126 + return STP_Bridge_Priority_Not_A_Multiple_Of_4096;
127 + }
128 +
129 if (uid_cfg->hello_time < MIN_BR_HELLOT) {
130 stp_trace ("%d hello_time small", (int) uid_cfg->hello_time);
131 return STP_Small_Hello_Time;
132 @@ -815,8 +820,13 @@
133 return 0;
134 }
135
136 +#ifdef ORIG
137 int
138 STP_IN_set_port_cfg (IN int vlan_id, IN UID_STP_PORT_CFG_T* uid_cfg)
139 +#else
140 +int
141 +STP_IN_set_port_cfg (int vlan_id, int port_index, UID_STP_PORT_CFG_T* uid_cfg)
142 +#endif
143 {
144 register STPM_T* this;
145 register PORT_T* port;
146 @@ -831,12 +841,21 @@
147 return STP_Vlan_Had_Not_Yet_Been_Created;
148 }
149
150 +#ifdef ORIG
151 for (port_no = 1; port_no <= max_port; port_no++) {
152 if (! BitmapGetBit(&uid_cfg->port_bmp, port_no - 1)) continue;
153 +#else
154 + port_no = port_index;
155 + {
156 +#endif
157
158 port = _stpapi_port_find (this, port_no);
159 if (! port) {/* port is absent in the stpm :( */
160 +#ifdef ORIG
161 continue;
162 +#else
163 + return STP_Port_Is_Absent_In_The_Vlan;
164 +#endif
165 }
166
167 if (PT_CFG_MCHECK & uid_cfg->field_mask) {
168 @@ -845,10 +864,18 @@
169 }
170
171 if (PT_CFG_COST & uid_cfg->field_mask) {
172 + if (uid_cfg->admin_port_path_cost > MAX_PORT_PCOST)
173 + return STP_Large_Port_PCost;
174 port->adminPCost = uid_cfg->admin_port_path_cost;
175 }
176
177 if (PT_CFG_PRIO & uid_cfg->field_mask) {
178 + if (uid_cfg->port_priority < MIN_PORT_PRIO)
179 + return STP_Small_Port_Priority;
180 + if (uid_cfg->port_priority > MAX_PORT_PRIO)
181 + return STP_Large_Port_Priority;
182 + if (uid_cfg->port_priority & ~MASK_PORT_PRIO)
183 + return STP_Port_Priority_Not_A_Multiple_Of_16;
184 port->port_id = (uid_cfg->port_priority << 8) + port_no;
185 }
186
187 @@ -955,3 +982,114 @@
188 return rstp_error_names[rstp_err_no];
189 }
190
191 +/*---------------- Dynamic port create / delete ------------------*/
192 +
193 +int STP_IN_port_create(int vlan_id, int port_index)
194 +{
195 + register STPM_T* this;
196 +
197 + this = stpapi_stpm_find (vlan_id);
198 +
199 + if (! this) { /* can't create stpm :( */
200 + return STP_Vlan_Had_Not_Yet_Been_Created;
201 + }
202 +
203 + PORT_T *port = STP_port_create (this, port_index);
204 + if (! port) {
205 + /* can't add port :( */
206 + stp_trace ("can't create port %d", (int) port_index);
207 + return STP_Cannot_Create_Instance_For_Port;
208 + }
209 + STP_port_init(port, this, True);
210 +
211 + STP_compute_bridge_id(this);
212 + STP_stpm_update_after_bridge_management (this);
213 + STP_stpm_update (this);
214 + return 0;
215 +}
216 +
217 +int STP_IN_port_delete(int vlan_id, int port_index)
218 +{
219 + register STPM_T* this;
220 + PORT_T *port;
221 +
222 + this = stpapi_stpm_find (vlan_id);
223 +
224 + if (! this) { /* can't find stpm :( */
225 + return STP_Vlan_Had_Not_Yet_Been_Created;
226 + }
227 +
228 + port = _stpapi_port_find (this, port_index);
229 + if (! port) {
230 + return STP_Port_Is_Absent_In_The_Vlan;
231 + }
232 +
233 + STP_port_delete (port);
234 +
235 + STP_compute_bridge_id(this);
236 + STP_stpm_update_after_bridge_management (this);
237 + STP_stpm_update (this);
238 + return 0;
239 +}
240 +
241 +
242 +/*--- For multiple STP instances - non multithread use ---*/
243 +
244 +struct stp_instance
245 +{
246 + STPM_T *bridges;
247 +#ifdef STP_DBG
248 + int dbg_rstp_deny;
249 +#endif
250 + int max_port; /* Remove this */
251 + int nev;
252 + RSTP_EVENT_T tev;
253 +};
254 +
255 +struct stp_instance *STP_IN_instance_create(void)
256 +{
257 + struct stp_instance *p;
258 + p = malloc(sizeof(*p));
259 + if (!p) return p;
260 + p->bridges = NULL;
261 +#ifdef STP_DBG
262 + p->dbg_rstp_deny = 0;
263 +#endif
264 + p->max_port = 1024;
265 + p->tev = RSTP_EVENT_LAST_DUMMY;
266 + p->nev = 0;
267 + return p;
268 +}
269 +
270 +void STP_IN_instance_begin(struct stp_instance *p)
271 +{
272 + bridges = p->bridges;
273 +#ifdef STP_DBG
274 + dbg_rstp_deny = p->dbg_rstp_deny;
275 +#endif
276 + max_port = p->max_port;
277 + tev = p->tev;
278 + nev = p->nev;
279 +}
280 +
281 +void STP_IN_instance_end(struct stp_instance *p)
282 +{
283 + p->bridges = bridges;
284 +#ifdef STP_DBG
285 + p->dbg_rstp_deny = dbg_rstp_deny;
286 +#endif
287 + p->max_port = max_port;
288 + p->tev = tev;
289 + p->nev = nev;
290 +}
291 +
292 +void STP_IN_instance_delete(struct stp_instance *p)
293 +{
294 + STP_IN_instance_begin(p);
295 + STP_IN_delete_all();
296 + STP_IN_instance_end(p);
297 + free(p);
298 +}
299 +
300 +
301 +
302 diff -Naur rstplib.1.1.02/stp_in.h rstplib/stp_in.h
303 --- rstplib.1.1.02/stp_in.h 2002-01-20 00:33:52.000000000 -0800
304 +++ rstplib/stp_in.h 2006-10-20 16:04:16.000000000 -0700
305 @@ -56,6 +56,7 @@
306 #define DEF_BR_PRIO 32768
307 #define MIN_BR_PRIO 0
308 #define MAX_BR_PRIO 61440
309 +#define MASK_BR_PRIO 0xf000
310
311 #define DEF_BR_HELLOT 2
312 #define MIN_BR_HELLOT 1
313 @@ -76,12 +77,15 @@
314 #define DEF_PORT_PRIO 128
315 #define MIN_PORT_PRIO 0
316 #define MAX_PORT_PRIO 240 /* in steps of 16 */
317 +#define MASK_PORT_PRIO 0xf0
318
319 #define DEF_ADMIN_NON_STP False
320 #define DEF_ADMIN_EDGE True
321 #define DEF_LINK_DELAY 3 /* see edge.c */
322 #define DEF_P2P P2P_AUTO
323
324 +#define MAX_PORT_PCOST 200000000
325 +
326 /* Section 1: Create/Delete/Start/Stop the RSTP instance */
327
328 void /* init the engine */
329 @@ -101,6 +105,12 @@
330 int
331 STP_IN_delete_all (void);
332
333 +/* Port create/delete */
334 +
335 +int STP_IN_port_create(int vlan_id, int port_index);
336 +
337 +int STP_IN_port_delete(int vlan_id, int port_index);
338 +
339 /* Section 2. "Get" management */
340
341 Bool
342 @@ -136,9 +146,15 @@
343 BITMAP_T* port_bmp,
344 UID_STP_CFG_T* uid_cfg);
345
346 +#ifdef ORIG
347 int
348 STP_IN_set_port_cfg (int vlan_id,
349 UID_STP_PORT_CFG_T* uid_cfg);
350 +#else
351 +int
352 +STP_IN_set_port_cfg (int vlan_id, int port_index,
353 + UID_STP_PORT_CFG_T* uid_cfg);
354 +#endif
355
356 #ifdef STP_DBG
357 int STP_IN_dbg_set_port_trace (char* mach_name, int enadis,
358 @@ -168,6 +184,19 @@
359 STP_IN_rx_bpdu (int vlan_id, int port_index, BPDU_T* bpdu, size_t len);
360 #endif
361
362 +/*--- For multiple STP instances - non multithread use ---*/
363 +
364 +struct stp_instance;
365 +/* Create struct to hold STP instance state and initialize it.
366 + A copy of all global state in the library. */
367 +struct stp_instance *STP_IN_instance_create(void);
368 +/* Set context from this STP instance */
369 +void STP_IN_instance_begin(struct stp_instance *p);
370 +/* Save context back to this STP instance */
371 +void STP_IN_instance_end(struct stp_instance *p);
372 +/* Delete this STP instance */
373 +void STP_IN_instance_delete(struct stp_instance *p);
374 +
375 #ifdef _STP_MACHINE_H__
376 /* Inner usage definitions & functions */
377
378 diff -Naur rstplib.1.1.02/stp_state.h rstplib/stp_state.h
379 --- rstplib.1.1.02/stp_state.h 1969-12-31 16:00:00.000000000 -0800
380 +++ rstplib/stp_state.h 2006-10-20 16:04:16.000000000 -0700
381 @@ -0,0 +1,7 @@
382 +#ifndef _STP_STATE_H__
383 +#define _STP_STATE_H__
384 +
385 +
386 +
387 +
388 +#endif
389 diff -Naur rstplib.1.1.02/stpm.c rstplib/stpm.c
390 --- rstplib.1.1.02/stpm.c 2002-01-20 00:34:14.000000000 -0800
391 +++ rstplib/stpm.c 2006-10-30 19:21:51.000000000 -0800
392 @@ -26,7 +26,11 @@
393 #include "stpm.h"
394 #include "stp_to.h" /* for STP_OUT_flush_lt */
395
396 -static STPM_T *bridges = NULL;
397 +/*static*/ STPM_T *bridges = NULL;
398 +
399 +/* We can flush learned fdb by port, so set this in stpm.c and topoch.c */
400 +/* This doesn't seem to solve the topology change problems. Don't use it yet */
401 +//#define STRONGLY_SPEC_802_1W
402
403 static int
404 _stp_stpm_init_machine (STATE_MACH_T* this)
405 @@ -217,9 +221,11 @@
406 {
407 register PORT_T* port;
408
409 +#ifdef ORIG
410 if (! this->ports) { /* there are not any ports :( */
411 return STP_There_Are_No_Ports;
412 }
413 +#endif
414
415 if (! STP_compute_bridge_id (this)) {/* can't compute bridge id ? :( */
416 return STP_Cannot_Compute_Bridge_Prio;
417 @@ -289,19 +295,16 @@
418 STP_compute_bridge_id (STPM_T* this)
419 {
420 register PORT_T* port;
421 - register PORT_T* min_num_port;
422 - int port_index = 0;
423 + unsigned char old[6], new[6];
424 + memset(&old, 0xff, sizeof(old));
425
426 for (port = this->ports; port; port = port->next) {
427 - if (! port_index || port->port_index < port_index) {
428 - min_num_port = port;
429 - port_index = port->port_index;
430 - }
431 + STP_OUT_get_port_mac (port->port_index, new);
432 + if (memcmp(new, old, sizeof(old)) < 0)
433 + memcpy(old, new, sizeof(old));
434 }
435
436 - if (! min_num_port) return NULL; /* IMHO, it may not be */
437 -
438 - STP_OUT_get_port_mac (min_num_port->port_index, this->BrId.addr);
439 + memcpy(this->BrId.addr, old, sizeof(old));
440
441 return &this->BrId;
442 }
443 diff -Naur rstplib.1.1.02/stpm.h rstplib/stpm.h
444 --- rstplib.1.1.02/stpm.h 2002-01-20 00:33:54.000000000 -0800
445 +++ rstplib/stpm.h 2006-10-20 16:04:16.000000000 -0700
446 @@ -103,6 +103,8 @@
447 STPM_T *
448 STP_stpm_get_the_list (void);
449
450 +extern STPM_T *bridges;
451 +
452 void
453 STP_stpm_update_after_bridge_management (STPM_T* this);
454
455 diff -Naur rstplib.1.1.02/stpmgmt.c rstplib/stpmgmt.c
456 --- rstplib.1.1.02/stpmgmt.c 2002-01-20 00:34:14.000000000 -0800
457 +++ rstplib/stpmgmt.c 2006-10-20 16:04:16.000000000 -0700
458 @@ -50,6 +50,11 @@
459 this->BrTimes.ForwardDelay = init_cfg.forward_delay;
460 this->ForceVersion = (PROTOCOL_VERSION_T) init_cfg.force_version;
461 }
462 +#ifdef ORIG
463 +#else
464 + if (this->admin_state != STP_ENABLED)
465 + err_code = STP_stpm_enable(this, STP_ENABLED);
466 +#endif
467
468 RSTP_CRITICAL_PATH_END;
469 return err_code;
470 @@ -145,10 +150,11 @@
471 int
472 STP_IN_delete_all (void)
473 {
474 - register STPM_T* stpm;
475 + register STPM_T* stpm, *next;
476
477 RSTP_CRITICAL_PATH_START;
478 - for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) {
479 + for (stpm = STP_stpm_get_the_list (); stpm; stpm = next) {
480 + next = stpm->next;
481 STP_stpm_enable (stpm, STP_DISABLED);
482 STP_stpm_delete (stpm);
483 }
484 diff -Naur rstplib.1.1.02/topoch.c rstplib/topoch.c
485 --- rstplib.1.1.02/topoch.c 2002-01-20 00:34:16.000000000 -0800
486 +++ rstplib/topoch.c 2006-10-30 19:22:01.000000000 -0800
487 @@ -40,6 +40,10 @@
488 #define GET_STATE_NAME STP_topoch_get_state_name
489 #include "choose.h"
490
491 +/* We can flush learned fdb by port, so set this in stpm.c and topoch.c */
492 +/* This doesn't seem to solve the topology change problems. Don't use it yet */
493 +//#define STRONGLY_SPEC_802_1W
494 +
495 #ifndef STRONGLY_SPEC_802_1W
496 /*
497 * In many kinds of hardware the function
498 @@ -61,12 +65,13 @@
499 if (this->debug) {
500 stp_trace("%s (%s, %s, %s, '%s')",
501 "flush", port->port_name, port->owner->name,
502 - LT_FLASH_ONLY_THE_PORT == type ? "this port" : "other ports",
503 + "this port",
504 reason);
505 }
506
507 bret = STP_OUT_flush_lt (port->port_index, port->owner->vlan_id,
508 LT_FLASH_ONLY_THE_PORT, reason);
509 + return bret;
510 }
511 #endif
512
513 @@ -103,7 +108,11 @@
514 if (port->sendRSTP && port->operPointToPointMac) {
515 return 2 * port->owner->rootTimes.HelloTime;
516 }
517 +#ifdef ORIG
518 return port->owner->rootTimes.MaxAge;
519 +#else
520 + return port->owner->rootTimes.MaxAge + port->owner->rootTimes.ForwardDelay;
521 +#endif
522 }
523
524 void
525 diff -Naur rstplib.1.1.02/transmit.c rstplib/transmit.c
526 --- rstplib.1.1.02/transmit.c 2002-01-20 00:34:17.000000000 -0800
527 +++ rstplib/transmit.c 2006-10-20 16:04:16.000000000 -0700
528 @@ -99,7 +99,11 @@
529 {
530 unsigned short len8023;
531
532 +#ifdef ORIG
533 STP_OUT_get_port_mac (port_index, bpdu_packet.mac.src_mac);
534 +#else
535 + /* Don't bother. LLC trasmits with correct source MAC, we don't supply it */
536 +#endif
537
538 bpdu_packet.hdr.bpdu_type = bpdu_type;
539 bpdu_packet.hdr.version = (BPDU_RSTP == bpdu_type) ?
540 @@ -110,7 +114,11 @@
541 len8023 = htons ((unsigned short) (pkt_len + 3));
542 memcpy (&bpdu_packet.eth.len8023, &len8023, 2);
543
544 +#ifdef ORIG
545 if (pkt_len < MIN_FRAME_LENGTH) pkt_len = MIN_FRAME_LENGTH;
546 +#else
547 + /* Don't do this. LLC puts in 802.3 length based on what we transmit */
548 +#endif
549 return pkt_len;
550 }
551
552 @@ -235,7 +243,7 @@
553
554 pkt_len = build_bpdu_header (port->port_index,
555 BPDU_RSTP,
556 - sizeof (BPDU_HEADER_T) + sizeof (BPDU_BODY_T) + 2);
557 + sizeof (BPDU_HEADER_T) + sizeof (BPDU_BODY_T) + 1);
558 build_config_bpdu (port, False);
559
560 switch (port->selectedRole) {
561 @@ -258,7 +266,12 @@
562 }
563
564 bpdu_packet.body.flags |= (role << PORT_ROLE_OFFS);
565 -
566 +#ifndef ORIG
567 + if (port->forwarding)
568 + bpdu_packet.body.flags |= FORWARD_BIT;
569 + if (port->learning)
570 + bpdu_packet.body.flags |= LEARN_BIT;
571 +#endif
572 if (port->synced) {
573 #if 0 /* def STP_DBG */
574 if (port->roletrns->debug)