]> git.ipfire.org Git - people/ms/rstp.git/blame - CHANGES_TO_RSTPLIB
Initial commit
[people/ms/rstp.git] / CHANGES_TO_RSTPLIB
CommitLineData
ad02a0eb
SH
1Some changes have been made to RSTPLIB version rsttplib.1.1.0.2 for use in this
2program. The changes are given in the following diff.
3The changes fall into 3 categories:
4
51. Changes to support dynamic addition and deletion of bridge ports.
62. Changes to support multiple bridges.
73. Fixes to protocol part based on 802.1w conformance testing results.
8
9
10diff -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__ */
46diff -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 }
70diff -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 =
85diff -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) {
117diff -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+
302diff -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
378diff -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
389diff -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 }
443diff -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
455diff -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 }
484diff -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
525diff -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)