xref: /onnv-gate/usr/src/lib/librstp/common/stpm.c (revision 10491:8893b747ecdf)
1*10491SRishi.Srivatsavai@Sun.COM /************************************************************************
2*10491SRishi.Srivatsavai@Sun.COM  * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
3*10491SRishi.Srivatsavai@Sun.COM  * Copyright (C) 2001-2003 Optical Access
4*10491SRishi.Srivatsavai@Sun.COM  * Author: Alex Rozin
5*10491SRishi.Srivatsavai@Sun.COM  *
6*10491SRishi.Srivatsavai@Sun.COM  * This file is part of RSTP library.
7*10491SRishi.Srivatsavai@Sun.COM  *
8*10491SRishi.Srivatsavai@Sun.COM  * RSTP library is free software; you can redistribute it and/or modify it
9*10491SRishi.Srivatsavai@Sun.COM  * under the terms of the GNU Lesser General Public License as published by the
10*10491SRishi.Srivatsavai@Sun.COM  * Free Software Foundation; version 2.1
11*10491SRishi.Srivatsavai@Sun.COM  *
12*10491SRishi.Srivatsavai@Sun.COM  * RSTP library is distributed in the hope that it will be useful, but
13*10491SRishi.Srivatsavai@Sun.COM  * WITHOUT ANY WARRANTY; without even the implied warranty of
14*10491SRishi.Srivatsavai@Sun.COM  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15*10491SRishi.Srivatsavai@Sun.COM  * General Public License for more details.
16*10491SRishi.Srivatsavai@Sun.COM  *
17*10491SRishi.Srivatsavai@Sun.COM  * You should have received a copy of the GNU Lesser General Public License
18*10491SRishi.Srivatsavai@Sun.COM  * along with RSTP library; see the file COPYING.  If not, write to the Free
19*10491SRishi.Srivatsavai@Sun.COM  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20*10491SRishi.Srivatsavai@Sun.COM  * 02111-1307, USA.
21*10491SRishi.Srivatsavai@Sun.COM  **********************************************************************/
22*10491SRishi.Srivatsavai@Sun.COM 
23*10491SRishi.Srivatsavai@Sun.COM  /* STP machine instance : bridge per VLAN: 17.17 */
24*10491SRishi.Srivatsavai@Sun.COM 
25*10491SRishi.Srivatsavai@Sun.COM #include "base.h"
26*10491SRishi.Srivatsavai@Sun.COM #include "stpm.h"
27*10491SRishi.Srivatsavai@Sun.COM #include "stp_to.h" /* for STP_OUT_flush_lt */
28*10491SRishi.Srivatsavai@Sun.COM 
29*10491SRishi.Srivatsavai@Sun.COM static STPM_T *bridges = NULL;
30*10491SRishi.Srivatsavai@Sun.COM 
31*10491SRishi.Srivatsavai@Sun.COM static int
_stp_stpm_init_machine(STATE_MACH_T * this)32*10491SRishi.Srivatsavai@Sun.COM _stp_stpm_init_machine (STATE_MACH_T* this)
33*10491SRishi.Srivatsavai@Sun.COM {
34*10491SRishi.Srivatsavai@Sun.COM   this->State = BEGIN;
35*10491SRishi.Srivatsavai@Sun.COM   (*(this->concreteEnterState)) (this);
36*10491SRishi.Srivatsavai@Sun.COM   return 0;
37*10491SRishi.Srivatsavai@Sun.COM }
38*10491SRishi.Srivatsavai@Sun.COM 
39*10491SRishi.Srivatsavai@Sun.COM static int
_stp_stpm_iterate_machines(STPM_T * this,int (* iter_callb)(STATE_MACH_T *),Bool exit_on_non_zero_ret)40*10491SRishi.Srivatsavai@Sun.COM _stp_stpm_iterate_machines (STPM_T* this,
41*10491SRishi.Srivatsavai@Sun.COM                            int (*iter_callb) (STATE_MACH_T*),
42*10491SRishi.Srivatsavai@Sun.COM                            Bool exit_on_non_zero_ret)
43*10491SRishi.Srivatsavai@Sun.COM {
44*10491SRishi.Srivatsavai@Sun.COM   register STATE_MACH_T* stater;
45*10491SRishi.Srivatsavai@Sun.COM   register PORT_T*       port;
46*10491SRishi.Srivatsavai@Sun.COM   int                    iret, mret = 0;
47*10491SRishi.Srivatsavai@Sun.COM 
48*10491SRishi.Srivatsavai@Sun.COM   /* state machines per bridge */
49*10491SRishi.Srivatsavai@Sun.COM   for (stater = this->machines; stater; stater = stater->next) {
50*10491SRishi.Srivatsavai@Sun.COM     iret = (*iter_callb) (stater);
51*10491SRishi.Srivatsavai@Sun.COM     if (exit_on_non_zero_ret && iret)
52*10491SRishi.Srivatsavai@Sun.COM       return iret;
53*10491SRishi.Srivatsavai@Sun.COM     else
54*10491SRishi.Srivatsavai@Sun.COM       mret += iret;
55*10491SRishi.Srivatsavai@Sun.COM   }
56*10491SRishi.Srivatsavai@Sun.COM 
57*10491SRishi.Srivatsavai@Sun.COM   /* state machines per port */
58*10491SRishi.Srivatsavai@Sun.COM   for (port = this->ports; port; port = port->next) {
59*10491SRishi.Srivatsavai@Sun.COM     for (stater = port->machines; stater; stater = stater->next) {
60*10491SRishi.Srivatsavai@Sun.COM       iret = (*iter_callb) (stater);
61*10491SRishi.Srivatsavai@Sun.COM       if (exit_on_non_zero_ret && iret)
62*10491SRishi.Srivatsavai@Sun.COM         return iret;
63*10491SRishi.Srivatsavai@Sun.COM       else
64*10491SRishi.Srivatsavai@Sun.COM         mret += iret;
65*10491SRishi.Srivatsavai@Sun.COM     }
66*10491SRishi.Srivatsavai@Sun.COM   }
67*10491SRishi.Srivatsavai@Sun.COM 
68*10491SRishi.Srivatsavai@Sun.COM   return mret;
69*10491SRishi.Srivatsavai@Sun.COM }
70*10491SRishi.Srivatsavai@Sun.COM 
71*10491SRishi.Srivatsavai@Sun.COM void
_stp_stpm_init_data(STPM_T * this)72*10491SRishi.Srivatsavai@Sun.COM _stp_stpm_init_data (STPM_T* this)
73*10491SRishi.Srivatsavai@Sun.COM {
74*10491SRishi.Srivatsavai@Sun.COM   STP_VECT_create (&this->rootPrio,
75*10491SRishi.Srivatsavai@Sun.COM                    &this->BrId,
76*10491SRishi.Srivatsavai@Sun.COM                    0,
77*10491SRishi.Srivatsavai@Sun.COM                    &this->BrId,
78*10491SRishi.Srivatsavai@Sun.COM                    0, 0);
79*10491SRishi.Srivatsavai@Sun.COM 
80*10491SRishi.Srivatsavai@Sun.COM   this->BrTimes.MessageAge = 0;
81*10491SRishi.Srivatsavai@Sun.COM 
82*10491SRishi.Srivatsavai@Sun.COM   STP_copy_times (&this->rootTimes, &this->BrTimes);
83*10491SRishi.Srivatsavai@Sun.COM }
84*10491SRishi.Srivatsavai@Sun.COM 
85*10491SRishi.Srivatsavai@Sun.COM static unsigned char
_check_topoch(STPM_T * this)86*10491SRishi.Srivatsavai@Sun.COM _check_topoch (STPM_T* this)
87*10491SRishi.Srivatsavai@Sun.COM {
88*10491SRishi.Srivatsavai@Sun.COM   register PORT_T*  port;
89*10491SRishi.Srivatsavai@Sun.COM 
90*10491SRishi.Srivatsavai@Sun.COM   for (port = this->ports; port; port = port->next) {
91*10491SRishi.Srivatsavai@Sun.COM     if (port->tcWhile) {
92*10491SRishi.Srivatsavai@Sun.COM       return 1;
93*10491SRishi.Srivatsavai@Sun.COM     }
94*10491SRishi.Srivatsavai@Sun.COM   }
95*10491SRishi.Srivatsavai@Sun.COM   return 0;
96*10491SRishi.Srivatsavai@Sun.COM }
97*10491SRishi.Srivatsavai@Sun.COM 
98*10491SRishi.Srivatsavai@Sun.COM void
STP_stpm_one_second(STPM_T * param)99*10491SRishi.Srivatsavai@Sun.COM STP_stpm_one_second (STPM_T* param)
100*10491SRishi.Srivatsavai@Sun.COM {
101*10491SRishi.Srivatsavai@Sun.COM   STPM_T*           this = (STPM_T*) param;
102*10491SRishi.Srivatsavai@Sun.COM   register PORT_T*  port;
103*10491SRishi.Srivatsavai@Sun.COM   register int      iii;
104*10491SRishi.Srivatsavai@Sun.COM 
105*10491SRishi.Srivatsavai@Sun.COM   if (STP_ENABLED != this->admin_state) return;
106*10491SRishi.Srivatsavai@Sun.COM 
107*10491SRishi.Srivatsavai@Sun.COM   for (port = this->ports; port; port = port->next) {
108*10491SRishi.Srivatsavai@Sun.COM     for (iii = 0; iii < TIMERS_NUMBER; iii++) {
109*10491SRishi.Srivatsavai@Sun.COM       if (*(port->timers[iii]) > 0) {
110*10491SRishi.Srivatsavai@Sun.COM         (*port->timers[iii])--;
111*10491SRishi.Srivatsavai@Sun.COM       }
112*10491SRishi.Srivatsavai@Sun.COM     }
113*10491SRishi.Srivatsavai@Sun.COM     port->uptime++;
114*10491SRishi.Srivatsavai@Sun.COM   }
115*10491SRishi.Srivatsavai@Sun.COM 
116*10491SRishi.Srivatsavai@Sun.COM   (void) STP_stpm_update (this);
117*10491SRishi.Srivatsavai@Sun.COM   this->Topo_Change = _check_topoch (this);
118*10491SRishi.Srivatsavai@Sun.COM   if (this->Topo_Change) {
119*10491SRishi.Srivatsavai@Sun.COM     this->Topo_Change_Count++;
120*10491SRishi.Srivatsavai@Sun.COM     this->timeSince_Topo_Change = 0;
121*10491SRishi.Srivatsavai@Sun.COM   } else {
122*10491SRishi.Srivatsavai@Sun.COM     this->Topo_Change_Count = 0;
123*10491SRishi.Srivatsavai@Sun.COM     this->timeSince_Topo_Change++;
124*10491SRishi.Srivatsavai@Sun.COM   }
125*10491SRishi.Srivatsavai@Sun.COM }
126*10491SRishi.Srivatsavai@Sun.COM 
127*10491SRishi.Srivatsavai@Sun.COM STPM_T*
STP_stpm_create(int vlan_id,char * name)128*10491SRishi.Srivatsavai@Sun.COM STP_stpm_create (int vlan_id, char* name)
129*10491SRishi.Srivatsavai@Sun.COM {
130*10491SRishi.Srivatsavai@Sun.COM   STPM_T* this;
131*10491SRishi.Srivatsavai@Sun.COM 
132*10491SRishi.Srivatsavai@Sun.COM   STP_NEW_IN_LIST(this, STPM_T, bridges, "stp instance");
133*10491SRishi.Srivatsavai@Sun.COM 
134*10491SRishi.Srivatsavai@Sun.COM   this->admin_state = STP_DISABLED;
135*10491SRishi.Srivatsavai@Sun.COM 
136*10491SRishi.Srivatsavai@Sun.COM   this->vlan_id = vlan_id;
137*10491SRishi.Srivatsavai@Sun.COM   if (name) {
138*10491SRishi.Srivatsavai@Sun.COM     STP_STRDUP(this->name, name, "stp bridge name");
139*10491SRishi.Srivatsavai@Sun.COM   }
140*10491SRishi.Srivatsavai@Sun.COM 
141*10491SRishi.Srivatsavai@Sun.COM   this->machines = NULL;
142*10491SRishi.Srivatsavai@Sun.COM   this->ports = NULL;
143*10491SRishi.Srivatsavai@Sun.COM 
144*10491SRishi.Srivatsavai@Sun.COM   STP_STATE_MACH_IN_LIST(rolesel);
145*10491SRishi.Srivatsavai@Sun.COM 
146*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
147*10491SRishi.Srivatsavai@Sun.COM   /* this->rolesel->debug = 2;  */
148*10491SRishi.Srivatsavai@Sun.COM #endif
149*10491SRishi.Srivatsavai@Sun.COM 
150*10491SRishi.Srivatsavai@Sun.COM   return this;
151*10491SRishi.Srivatsavai@Sun.COM }
152*10491SRishi.Srivatsavai@Sun.COM 
153*10491SRishi.Srivatsavai@Sun.COM int
STP_stpm_enable(STPM_T * this,UID_STP_MODE_T admin_state)154*10491SRishi.Srivatsavai@Sun.COM STP_stpm_enable (STPM_T* this, UID_STP_MODE_T admin_state)
155*10491SRishi.Srivatsavai@Sun.COM {
156*10491SRishi.Srivatsavai@Sun.COM   int rc = 0;
157*10491SRishi.Srivatsavai@Sun.COM 
158*10491SRishi.Srivatsavai@Sun.COM   if (admin_state == this->admin_state) {
159*10491SRishi.Srivatsavai@Sun.COM     /* nothing to do :) */
160*10491SRishi.Srivatsavai@Sun.COM     return 0;
161*10491SRishi.Srivatsavai@Sun.COM   }
162*10491SRishi.Srivatsavai@Sun.COM 
163*10491SRishi.Srivatsavai@Sun.COM   if (STP_ENABLED == admin_state) {
164*10491SRishi.Srivatsavai@Sun.COM     if (this->ports)
165*10491SRishi.Srivatsavai@Sun.COM       rc = STP_stpm_start (this);
166*10491SRishi.Srivatsavai@Sun.COM     this->admin_state = admin_state;
167*10491SRishi.Srivatsavai@Sun.COM   } else {
168*10491SRishi.Srivatsavai@Sun.COM     this->admin_state = admin_state;
169*10491SRishi.Srivatsavai@Sun.COM     STP_stpm_stop (this);
170*10491SRishi.Srivatsavai@Sun.COM   }
171*10491SRishi.Srivatsavai@Sun.COM 
172*10491SRishi.Srivatsavai@Sun.COM   return rc;
173*10491SRishi.Srivatsavai@Sun.COM }
174*10491SRishi.Srivatsavai@Sun.COM 
175*10491SRishi.Srivatsavai@Sun.COM void
STP_stpm_delete(STPM_T * this)176*10491SRishi.Srivatsavai@Sun.COM STP_stpm_delete (STPM_T* this)
177*10491SRishi.Srivatsavai@Sun.COM {
178*10491SRishi.Srivatsavai@Sun.COM   register STPM_T*       tmp;
179*10491SRishi.Srivatsavai@Sun.COM   register STPM_T*       prev;
180*10491SRishi.Srivatsavai@Sun.COM   register STATE_MACH_T* stater;
181*10491SRishi.Srivatsavai@Sun.COM   register PORT_T*       port;
182*10491SRishi.Srivatsavai@Sun.COM   register void*         pv;
183*10491SRishi.Srivatsavai@Sun.COM 
184*10491SRishi.Srivatsavai@Sun.COM   (void) STP_stpm_enable (this, STP_DISABLED);
185*10491SRishi.Srivatsavai@Sun.COM 
186*10491SRishi.Srivatsavai@Sun.COM   for (stater = this->machines; stater; ) {
187*10491SRishi.Srivatsavai@Sun.COM     pv = (void*) stater->next;
188*10491SRishi.Srivatsavai@Sun.COM     STP_state_mach_delete (stater);
189*10491SRishi.Srivatsavai@Sun.COM     this->machines = stater = (STATE_MACH_T*) pv;
190*10491SRishi.Srivatsavai@Sun.COM   }
191*10491SRishi.Srivatsavai@Sun.COM 
192*10491SRishi.Srivatsavai@Sun.COM   for (port = this->ports; port; ) {
193*10491SRishi.Srivatsavai@Sun.COM     pv = (void*) port->next;
194*10491SRishi.Srivatsavai@Sun.COM     STP_port_delete (port);
195*10491SRishi.Srivatsavai@Sun.COM     this->ports = port = (PORT_T*) pv;
196*10491SRishi.Srivatsavai@Sun.COM   }
197*10491SRishi.Srivatsavai@Sun.COM 
198*10491SRishi.Srivatsavai@Sun.COM   prev = NULL;
199*10491SRishi.Srivatsavai@Sun.COM   for (tmp = bridges; tmp; tmp = tmp->next) {
200*10491SRishi.Srivatsavai@Sun.COM     if (tmp->vlan_id == this->vlan_id) {
201*10491SRishi.Srivatsavai@Sun.COM       if (prev) {
202*10491SRishi.Srivatsavai@Sun.COM         prev->next = this->next;
203*10491SRishi.Srivatsavai@Sun.COM       } else {
204*10491SRishi.Srivatsavai@Sun.COM         bridges = this->next;
205*10491SRishi.Srivatsavai@Sun.COM       }
206*10491SRishi.Srivatsavai@Sun.COM 
207*10491SRishi.Srivatsavai@Sun.COM       if (this->name)
208*10491SRishi.Srivatsavai@Sun.COM         STP_FREE(this->name, "stp bridge name");
209*10491SRishi.Srivatsavai@Sun.COM       STP_FREE(this, "stp instance");
210*10491SRishi.Srivatsavai@Sun.COM       break;
211*10491SRishi.Srivatsavai@Sun.COM     }
212*10491SRishi.Srivatsavai@Sun.COM     prev = tmp;
213*10491SRishi.Srivatsavai@Sun.COM   }
214*10491SRishi.Srivatsavai@Sun.COM }
215*10491SRishi.Srivatsavai@Sun.COM 
216*10491SRishi.Srivatsavai@Sun.COM int
STP_stpm_start(STPM_T * this)217*10491SRishi.Srivatsavai@Sun.COM STP_stpm_start (STPM_T* this)
218*10491SRishi.Srivatsavai@Sun.COM {
219*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port;
220*10491SRishi.Srivatsavai@Sun.COM 
221*10491SRishi.Srivatsavai@Sun.COM   if (! this->ports) { /* there are not any ports :( */
222*10491SRishi.Srivatsavai@Sun.COM     return STP_There_Are_No_Ports;
223*10491SRishi.Srivatsavai@Sun.COM   }
224*10491SRishi.Srivatsavai@Sun.COM 
225*10491SRishi.Srivatsavai@Sun.COM   if (! STP_compute_bridge_id (this)) {/* can't compute bridge id ? :( */
226*10491SRishi.Srivatsavai@Sun.COM     return STP_Cannot_Compute_Bridge_Prio;
227*10491SRishi.Srivatsavai@Sun.COM   }
228*10491SRishi.Srivatsavai@Sun.COM 
229*10491SRishi.Srivatsavai@Sun.COM   /* check, that the stpm has unique bridge Id */
230*10491SRishi.Srivatsavai@Sun.COM   if (0 != STP_stpm_check_bridge_priority (this)) {
231*10491SRishi.Srivatsavai@Sun.COM     /* there is an enabled bridge with same ID :( */
232*10491SRishi.Srivatsavai@Sun.COM     return STP_Invalid_Bridge_Priority;
233*10491SRishi.Srivatsavai@Sun.COM   }
234*10491SRishi.Srivatsavai@Sun.COM 
235*10491SRishi.Srivatsavai@Sun.COM   _stp_stpm_init_data (this);
236*10491SRishi.Srivatsavai@Sun.COM 
237*10491SRishi.Srivatsavai@Sun.COM   for (port = this->ports; port; port = port->next) {
238*10491SRishi.Srivatsavai@Sun.COM     STP_port_init (port, this, True);
239*10491SRishi.Srivatsavai@Sun.COM   }
240*10491SRishi.Srivatsavai@Sun.COM 
241*10491SRishi.Srivatsavai@Sun.COM #ifndef STRONGLY_SPEC_802_1W
242*10491SRishi.Srivatsavai@Sun.COM   /* A. see comment near STRONGLY_SPEC_802_1W in topoch.c */
243*10491SRishi.Srivatsavai@Sun.COM   /* B. port=0 here means: delete for all ports */
244*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
245*10491SRishi.Srivatsavai@Sun.COM   stp_trace("%s (all, start stpm)",
246*10491SRishi.Srivatsavai@Sun.COM         "clearFDB");
247*10491SRishi.Srivatsavai@Sun.COM #endif
248*10491SRishi.Srivatsavai@Sun.COM 
249*10491SRishi.Srivatsavai@Sun.COM   STP_OUT_flush_lt (0, this->vlan_id, LT_FLASH_ONLY_THE_PORT, "start stpm");
250*10491SRishi.Srivatsavai@Sun.COM #endif
251*10491SRishi.Srivatsavai@Sun.COM 
252*10491SRishi.Srivatsavai@Sun.COM   (void) _stp_stpm_iterate_machines (this, _stp_stpm_init_machine, False);
253*10491SRishi.Srivatsavai@Sun.COM   (void) STP_stpm_update (this);
254*10491SRishi.Srivatsavai@Sun.COM 
255*10491SRishi.Srivatsavai@Sun.COM   return 0;
256*10491SRishi.Srivatsavai@Sun.COM }
257*10491SRishi.Srivatsavai@Sun.COM 
258*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */
259*10491SRishi.Srivatsavai@Sun.COM void
STP_stpm_stop(STPM_T * this)260*10491SRishi.Srivatsavai@Sun.COM STP_stpm_stop (STPM_T* this)
261*10491SRishi.Srivatsavai@Sun.COM {
262*10491SRishi.Srivatsavai@Sun.COM }
263*10491SRishi.Srivatsavai@Sun.COM 
264*10491SRishi.Srivatsavai@Sun.COM int
STP_stpm_update(STPM_T * this)265*10491SRishi.Srivatsavai@Sun.COM STP_stpm_update (STPM_T* this) /* returns number of loops */
266*10491SRishi.Srivatsavai@Sun.COM {
267*10491SRishi.Srivatsavai@Sun.COM   register Bool     need_state_change;
268*10491SRishi.Srivatsavai@Sun.COM   register int      number_of_loops = 0;
269*10491SRishi.Srivatsavai@Sun.COM 
270*10491SRishi.Srivatsavai@Sun.COM   need_state_change = False;
271*10491SRishi.Srivatsavai@Sun.COM 
272*10491SRishi.Srivatsavai@Sun.COM   for (;;) {/* loop until not need changes */
273*10491SRishi.Srivatsavai@Sun.COM     need_state_change = _stp_stpm_iterate_machines (this,
274*10491SRishi.Srivatsavai@Sun.COM                                                    STP_check_condition,
275*10491SRishi.Srivatsavai@Sun.COM                                                    True);
276*10491SRishi.Srivatsavai@Sun.COM     if (! need_state_change) break;
277*10491SRishi.Srivatsavai@Sun.COM 
278*10491SRishi.Srivatsavai@Sun.COM     number_of_loops++;
279*10491SRishi.Srivatsavai@Sun.COM     /* here we know, that at least one stater must be
280*10491SRishi.Srivatsavai@Sun.COM        updated (it has changed state) */
281*10491SRishi.Srivatsavai@Sun.COM     number_of_loops += _stp_stpm_iterate_machines (this,
282*10491SRishi.Srivatsavai@Sun.COM                                                   STP_change_state,
283*10491SRishi.Srivatsavai@Sun.COM                                                   False);
284*10491SRishi.Srivatsavai@Sun.COM 
285*10491SRishi.Srivatsavai@Sun.COM   }
286*10491SRishi.Srivatsavai@Sun.COM 
287*10491SRishi.Srivatsavai@Sun.COM   return number_of_loops;
288*10491SRishi.Srivatsavai@Sun.COM }
289*10491SRishi.Srivatsavai@Sun.COM 
290*10491SRishi.Srivatsavai@Sun.COM BRIDGE_ID *
STP_compute_bridge_id(STPM_T * this)291*10491SRishi.Srivatsavai@Sun.COM STP_compute_bridge_id (STPM_T* this)
292*10491SRishi.Srivatsavai@Sun.COM {
293*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port;
294*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* min_num_port = NULL;
295*10491SRishi.Srivatsavai@Sun.COM   int              port_index = 0;
296*10491SRishi.Srivatsavai@Sun.COM 
297*10491SRishi.Srivatsavai@Sun.COM   for (port = this->ports; port; port = port->next) {
298*10491SRishi.Srivatsavai@Sun.COM     if (! port_index || port->port_index < port_index) {
299*10491SRishi.Srivatsavai@Sun.COM       min_num_port = port;
300*10491SRishi.Srivatsavai@Sun.COM       port_index = port->port_index;
301*10491SRishi.Srivatsavai@Sun.COM     }
302*10491SRishi.Srivatsavai@Sun.COM   }
303*10491SRishi.Srivatsavai@Sun.COM 
304*10491SRishi.Srivatsavai@Sun.COM   if (! min_num_port) return NULL; /* IMHO, it may not be */
305*10491SRishi.Srivatsavai@Sun.COM 
306*10491SRishi.Srivatsavai@Sun.COM   STP_OUT_get_port_mac (min_num_port->port_index, this->BrId.addr);
307*10491SRishi.Srivatsavai@Sun.COM 
308*10491SRishi.Srivatsavai@Sun.COM   return &this->BrId;
309*10491SRishi.Srivatsavai@Sun.COM }
310*10491SRishi.Srivatsavai@Sun.COM 
311*10491SRishi.Srivatsavai@Sun.COM STPM_T*
STP_stpm_get_the_list(void)312*10491SRishi.Srivatsavai@Sun.COM STP_stpm_get_the_list (void)
313*10491SRishi.Srivatsavai@Sun.COM {
314*10491SRishi.Srivatsavai@Sun.COM   return bridges;
315*10491SRishi.Srivatsavai@Sun.COM }
316*10491SRishi.Srivatsavai@Sun.COM 
317*10491SRishi.Srivatsavai@Sun.COM void
STP_stpm_update_after_bridge_management(STPM_T * this)318*10491SRishi.Srivatsavai@Sun.COM STP_stpm_update_after_bridge_management (STPM_T* this)
319*10491SRishi.Srivatsavai@Sun.COM {
320*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port;
321*10491SRishi.Srivatsavai@Sun.COM 
322*10491SRishi.Srivatsavai@Sun.COM   for (port = this->ports; port; port = port->next) {
323*10491SRishi.Srivatsavai@Sun.COM     port->reselect = True;
324*10491SRishi.Srivatsavai@Sun.COM     port->selected = False;
325*10491SRishi.Srivatsavai@Sun.COM   }
326*10491SRishi.Srivatsavai@Sun.COM }
327*10491SRishi.Srivatsavai@Sun.COM 
328*10491SRishi.Srivatsavai@Sun.COM int
STP_stpm_check_bridge_priority(STPM_T * this)329*10491SRishi.Srivatsavai@Sun.COM STP_stpm_check_bridge_priority (STPM_T* this)
330*10491SRishi.Srivatsavai@Sun.COM {
331*10491SRishi.Srivatsavai@Sun.COM   register STPM_T* oth;
332*10491SRishi.Srivatsavai@Sun.COM 
333*10491SRishi.Srivatsavai@Sun.COM   for (oth = bridges; oth; oth = oth->next) {
334*10491SRishi.Srivatsavai@Sun.COM     if (STP_ENABLED == oth->admin_state && oth != this &&
335*10491SRishi.Srivatsavai@Sun.COM         ! STP_VECT_compare_bridge_id (&this->BrId, &oth->BrId)) {
336*10491SRishi.Srivatsavai@Sun.COM       return STP_Invalid_Bridge_Priority;
337*10491SRishi.Srivatsavai@Sun.COM     }
338*10491SRishi.Srivatsavai@Sun.COM   }
339*10491SRishi.Srivatsavai@Sun.COM 
340*10491SRishi.Srivatsavai@Sun.COM   return 0;
341*10491SRishi.Srivatsavai@Sun.COM }
342*10491SRishi.Srivatsavai@Sun.COM 
343*10491SRishi.Srivatsavai@Sun.COM const char*
STP_stpm_get_port_name_by_id(STPM_T * this,PORT_ID port_id)344*10491SRishi.Srivatsavai@Sun.COM STP_stpm_get_port_name_by_id (STPM_T* this, PORT_ID port_id)
345*10491SRishi.Srivatsavai@Sun.COM {
346*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port;
347*10491SRishi.Srivatsavai@Sun.COM 
348*10491SRishi.Srivatsavai@Sun.COM   for (port = this->ports; port; port = port->next) {
349*10491SRishi.Srivatsavai@Sun.COM     if (port_id == port->port_id) {
350*10491SRishi.Srivatsavai@Sun.COM         return port->port_name;
351*10491SRishi.Srivatsavai@Sun.COM     }
352*10491SRishi.Srivatsavai@Sun.COM   }
353*10491SRishi.Srivatsavai@Sun.COM 
354*10491SRishi.Srivatsavai@Sun.COM   return "Undef?";
355*10491SRishi.Srivatsavai@Sun.COM }
356*10491SRishi.Srivatsavai@Sun.COM 
357*10491SRishi.Srivatsavai@Sun.COM 
358*10491SRishi.Srivatsavai@Sun.COM 
359*10491SRishi.Srivatsavai@Sun.COM 
360*10491SRishi.Srivatsavai@Sun.COM 
361