xref: /titanic_52/usr/src/lib/librstp/common/stp_in.c (revision 4eaa471005973e11a6110b69fe990530b3b95a38)
1*4eaa4710SRishi Srivatsavai /************************************************************************
2*4eaa4710SRishi Srivatsavai  * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
3*4eaa4710SRishi Srivatsavai  * Copyright (C) 2001-2003 Optical Access
4*4eaa4710SRishi Srivatsavai  * Author: Alex Rozin
5*4eaa4710SRishi Srivatsavai  *
6*4eaa4710SRishi Srivatsavai  * This file is part of RSTP library.
7*4eaa4710SRishi Srivatsavai  *
8*4eaa4710SRishi Srivatsavai  * RSTP library is free software; you can redistribute it and/or modify it
9*4eaa4710SRishi Srivatsavai  * under the terms of the GNU Lesser General Public License as published by the
10*4eaa4710SRishi Srivatsavai  * Free Software Foundation; version 2.1
11*4eaa4710SRishi Srivatsavai  *
12*4eaa4710SRishi Srivatsavai  * RSTP library is distributed in the hope that it will be useful, but
13*4eaa4710SRishi Srivatsavai  * WITHOUT ANY WARRANTY; without even the implied warranty of
14*4eaa4710SRishi Srivatsavai  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15*4eaa4710SRishi Srivatsavai  * General Public License for more details.
16*4eaa4710SRishi Srivatsavai  *
17*4eaa4710SRishi Srivatsavai  * You should have received a copy of the GNU Lesser General Public License
18*4eaa4710SRishi Srivatsavai  * along with RSTP library; see the file COPYING.  If not, write to the Free
19*4eaa4710SRishi Srivatsavai  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20*4eaa4710SRishi Srivatsavai  * 02111-1307, USA.
21*4eaa4710SRishi Srivatsavai  **********************************************************************/
22*4eaa4710SRishi Srivatsavai 
23*4eaa4710SRishi Srivatsavai /* This file contains API from an operation system to the RSTP library */
24*4eaa4710SRishi Srivatsavai 
25*4eaa4710SRishi Srivatsavai #include "base.h"
26*4eaa4710SRishi Srivatsavai #include "stpm.h"
27*4eaa4710SRishi Srivatsavai #include "stp_in.h"
28*4eaa4710SRishi Srivatsavai #include "stp_to.h"
29*4eaa4710SRishi Srivatsavai 
30*4eaa4710SRishi Srivatsavai #define _stp_in_stpm_enable stp_in_stpm_enable
31*4eaa4710SRishi Srivatsavai 
32*4eaa4710SRishi Srivatsavai STP_VECTORS_T *stp_vectors;
33*4eaa4710SRishi Srivatsavai 
34*4eaa4710SRishi Srivatsavai void *
35*4eaa4710SRishi Srivatsavai stp_in_stpm_create (int vlan_id, char* name, int* err_code)
36*4eaa4710SRishi Srivatsavai {
37*4eaa4710SRishi Srivatsavai   register STPM_T* this;
38*4eaa4710SRishi Srivatsavai 
39*4eaa4710SRishi Srivatsavai   /* stp_trace ("stp_in_stpm_create(%s)", name); */
40*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
41*4eaa4710SRishi Srivatsavai   if (this) { /* it had just been created :( */
42*4eaa4710SRishi Srivatsavai     *err_code = STP_Nothing_To_Do;
43*4eaa4710SRishi Srivatsavai     return this;
44*4eaa4710SRishi Srivatsavai   }
45*4eaa4710SRishi Srivatsavai 
46*4eaa4710SRishi Srivatsavai   this = STP_stpm_create (vlan_id, name);
47*4eaa4710SRishi Srivatsavai   if (! this) { /* can't create stpm :( */
48*4eaa4710SRishi Srivatsavai     *err_code = STP_Cannot_Create_Instance_For_Vlan;
49*4eaa4710SRishi Srivatsavai     return NULL;
50*4eaa4710SRishi Srivatsavai   }
51*4eaa4710SRishi Srivatsavai 
52*4eaa4710SRishi Srivatsavai   *err_code = STP_OK;
53*4eaa4710SRishi Srivatsavai   return this;
54*4eaa4710SRishi Srivatsavai }
55*4eaa4710SRishi Srivatsavai 
56*4eaa4710SRishi Srivatsavai int
57*4eaa4710SRishi Srivatsavai _stp_in_stpm_enable (int vlan_id, char* name,
58*4eaa4710SRishi Srivatsavai                     UID_STP_MODE_T admin_state)
59*4eaa4710SRishi Srivatsavai {
60*4eaa4710SRishi Srivatsavai   register STPM_T* this;
61*4eaa4710SRishi Srivatsavai   Bool created_here = False;
62*4eaa4710SRishi Srivatsavai   int rc, err_code;
63*4eaa4710SRishi Srivatsavai 
64*4eaa4710SRishi Srivatsavai   /* stp_trace ("_stp_in_stpm_enable(%s)", name); */
65*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
66*4eaa4710SRishi Srivatsavai 
67*4eaa4710SRishi Srivatsavai   if (STP_DISABLED != admin_state) {
68*4eaa4710SRishi Srivatsavai     if (! vlan_id) { /* STP_IN_stop_all (); */
69*4eaa4710SRishi Srivatsavai         register STPM_T* stpm;
70*4eaa4710SRishi Srivatsavai 
71*4eaa4710SRishi Srivatsavai         for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) {
72*4eaa4710SRishi Srivatsavai           if (STP_DISABLED != stpm->admin_state) {
73*4eaa4710SRishi Srivatsavai             STP_OUT_set_hardware_mode (stpm->vlan_id, STP_DISABLED);
74*4eaa4710SRishi Srivatsavai             (void) STP_stpm_enable (stpm, STP_DISABLED);
75*4eaa4710SRishi Srivatsavai           }
76*4eaa4710SRishi Srivatsavai         }
77*4eaa4710SRishi Srivatsavai     }
78*4eaa4710SRishi Srivatsavai   }
79*4eaa4710SRishi Srivatsavai 
80*4eaa4710SRishi Srivatsavai   if (! this) { /* it had not yet been created */
81*4eaa4710SRishi Srivatsavai     if (STP_ENABLED == admin_state) {/* try to create it */
82*4eaa4710SRishi Srivatsavai       stp_trace ("implicit create to vlan '%s'", name);
83*4eaa4710SRishi Srivatsavai       this = stp_in_stpm_create (vlan_id, name, &err_code);
84*4eaa4710SRishi Srivatsavai       if (! this) {
85*4eaa4710SRishi Srivatsavai         stp_trace ("implicit create to vlan '%s' failed", name);
86*4eaa4710SRishi Srivatsavai         return STP_Implicit_Instance_Create_Failed;
87*4eaa4710SRishi Srivatsavai       }
88*4eaa4710SRishi Srivatsavai       created_here = True;
89*4eaa4710SRishi Srivatsavai     } else {/* try to disable nothing ? */
90*4eaa4710SRishi Srivatsavai       return 0;
91*4eaa4710SRishi Srivatsavai     }
92*4eaa4710SRishi Srivatsavai   }
93*4eaa4710SRishi Srivatsavai 
94*4eaa4710SRishi Srivatsavai   if (this->admin_state == admin_state) { /* nothing to do :) */
95*4eaa4710SRishi Srivatsavai     return 0;
96*4eaa4710SRishi Srivatsavai   }
97*4eaa4710SRishi Srivatsavai 
98*4eaa4710SRishi Srivatsavai   rc = STP_stpm_enable (this, admin_state);
99*4eaa4710SRishi Srivatsavai   if (! rc) {
100*4eaa4710SRishi Srivatsavai     STP_OUT_set_hardware_mode (vlan_id, admin_state);
101*4eaa4710SRishi Srivatsavai   }
102*4eaa4710SRishi Srivatsavai 
103*4eaa4710SRishi Srivatsavai   if (rc && created_here) {
104*4eaa4710SRishi Srivatsavai     STP_stpm_delete (this);
105*4eaa4710SRishi Srivatsavai   }
106*4eaa4710SRishi Srivatsavai 
107*4eaa4710SRishi Srivatsavai   return rc;
108*4eaa4710SRishi Srivatsavai }
109*4eaa4710SRishi Srivatsavai 
110*4eaa4710SRishi Srivatsavai 
111*4eaa4710SRishi Srivatsavai STPM_T *
112*4eaa4710SRishi Srivatsavai stpapi_stpm_find (int vlan_id)
113*4eaa4710SRishi Srivatsavai {
114*4eaa4710SRishi Srivatsavai   register STPM_T* this;
115*4eaa4710SRishi Srivatsavai 
116*4eaa4710SRishi Srivatsavai   for (this = STP_stpm_get_the_list (); this; this = this->next)
117*4eaa4710SRishi Srivatsavai     if (vlan_id == this->vlan_id)
118*4eaa4710SRishi Srivatsavai       return this;
119*4eaa4710SRishi Srivatsavai 
120*4eaa4710SRishi Srivatsavai   return NULL;
121*4eaa4710SRishi Srivatsavai }
122*4eaa4710SRishi Srivatsavai 
123*4eaa4710SRishi Srivatsavai static PORT_T *
124*4eaa4710SRishi Srivatsavai _stpapi_port_find (STPM_T* this, int port_index)
125*4eaa4710SRishi Srivatsavai {
126*4eaa4710SRishi Srivatsavai   register PORT_T* port;
127*4eaa4710SRishi Srivatsavai 
128*4eaa4710SRishi Srivatsavai   for (port = this->ports; port; port = port->next)
129*4eaa4710SRishi Srivatsavai     if (port_index == port->port_index) {
130*4eaa4710SRishi Srivatsavai       return port;
131*4eaa4710SRishi Srivatsavai     }
132*4eaa4710SRishi Srivatsavai 
133*4eaa4710SRishi Srivatsavai   return NULL;
134*4eaa4710SRishi Srivatsavai }
135*4eaa4710SRishi Srivatsavai 
136*4eaa4710SRishi Srivatsavai 
137*4eaa4710SRishi Srivatsavai static void
138*4eaa4710SRishi Srivatsavai _conv_br_id_2_uid (IN BRIDGE_ID* f, OUT UID_BRIDGE_ID_T* t)
139*4eaa4710SRishi Srivatsavai {
140*4eaa4710SRishi Srivatsavai   (void) memcpy (t, f, sizeof (UID_BRIDGE_ID_T));
141*4eaa4710SRishi Srivatsavai }
142*4eaa4710SRishi Srivatsavai 
143*4eaa4710SRishi Srivatsavai static int
144*4eaa4710SRishi Srivatsavai _check_stpm_config (IN UID_STP_CFG_T* uid_cfg)
145*4eaa4710SRishi Srivatsavai {
146*4eaa4710SRishi Srivatsavai   if (uid_cfg->bridge_priority < MIN_BR_PRIO) {
147*4eaa4710SRishi Srivatsavai     stp_trace ("%d bridge_priority small", (int) uid_cfg->bridge_priority);
148*4eaa4710SRishi Srivatsavai     return STP_Small_Bridge_Priority;
149*4eaa4710SRishi Srivatsavai   }
150*4eaa4710SRishi Srivatsavai 
151*4eaa4710SRishi Srivatsavai   if (uid_cfg->bridge_priority > MAX_BR_PRIO) {
152*4eaa4710SRishi Srivatsavai     stp_trace ("%d bridge_priority large", (int) uid_cfg->bridge_priority);
153*4eaa4710SRishi Srivatsavai     return STP_Large_Bridge_Priority;
154*4eaa4710SRishi Srivatsavai   }
155*4eaa4710SRishi Srivatsavai 
156*4eaa4710SRishi Srivatsavai   if (uid_cfg->hello_time < MIN_BR_HELLOT) {
157*4eaa4710SRishi Srivatsavai     stp_trace ("%d hello_time small", (int) uid_cfg->hello_time);
158*4eaa4710SRishi Srivatsavai     return STP_Small_Hello_Time;
159*4eaa4710SRishi Srivatsavai   }
160*4eaa4710SRishi Srivatsavai 
161*4eaa4710SRishi Srivatsavai   if (uid_cfg->hello_time > MAX_BR_HELLOT) {
162*4eaa4710SRishi Srivatsavai     stp_trace ("%d hello_time large", (int) uid_cfg->hello_time);
163*4eaa4710SRishi Srivatsavai     return STP_Large_Hello_Time;
164*4eaa4710SRishi Srivatsavai   }
165*4eaa4710SRishi Srivatsavai 
166*4eaa4710SRishi Srivatsavai   if (uid_cfg->max_age < MIN_BR_MAXAGE) {
167*4eaa4710SRishi Srivatsavai     stp_trace ("%d max_age small", (int) uid_cfg->max_age);
168*4eaa4710SRishi Srivatsavai     return STP_Small_Max_Age;
169*4eaa4710SRishi Srivatsavai   }
170*4eaa4710SRishi Srivatsavai 
171*4eaa4710SRishi Srivatsavai   if (uid_cfg->max_age > MAX_BR_MAXAGE) {
172*4eaa4710SRishi Srivatsavai     stp_trace ("%d max_age large", (int) uid_cfg->max_age);
173*4eaa4710SRishi Srivatsavai     return STP_Large_Max_Age;
174*4eaa4710SRishi Srivatsavai   }
175*4eaa4710SRishi Srivatsavai 
176*4eaa4710SRishi Srivatsavai   if (uid_cfg->forward_delay < MIN_BR_FWDELAY) {
177*4eaa4710SRishi Srivatsavai     stp_trace ("%d forward_delay small", (int) uid_cfg->forward_delay);
178*4eaa4710SRishi Srivatsavai     return STP_Small_Forward_Delay;
179*4eaa4710SRishi Srivatsavai   }
180*4eaa4710SRishi Srivatsavai 
181*4eaa4710SRishi Srivatsavai   if (uid_cfg->forward_delay > MAX_BR_FWDELAY) {
182*4eaa4710SRishi Srivatsavai     stp_trace ("%d forward_delay large", (int) uid_cfg->forward_delay);
183*4eaa4710SRishi Srivatsavai     return STP_Large_Forward_Delay;
184*4eaa4710SRishi Srivatsavai   }
185*4eaa4710SRishi Srivatsavai 
186*4eaa4710SRishi Srivatsavai   if (2 * (uid_cfg->forward_delay - 1) < uid_cfg->max_age) {
187*4eaa4710SRishi Srivatsavai     return STP_Forward_Delay_And_Max_Age_Are_Inconsistent;
188*4eaa4710SRishi Srivatsavai   }
189*4eaa4710SRishi Srivatsavai 
190*4eaa4710SRishi Srivatsavai   if (uid_cfg->max_age < 2 * (uid_cfg->hello_time + 1)) {
191*4eaa4710SRishi Srivatsavai     return STP_Hello_Time_And_Max_Age_Are_Inconsistent;
192*4eaa4710SRishi Srivatsavai   }
193*4eaa4710SRishi Srivatsavai 
194*4eaa4710SRishi Srivatsavai   return 0;
195*4eaa4710SRishi Srivatsavai }
196*4eaa4710SRishi Srivatsavai 
197*4eaa4710SRishi Srivatsavai static void
198*4eaa4710SRishi Srivatsavai _stp_in_enable_port_on_stpm (STPM_T* stpm, int port_index, Bool enable)
199*4eaa4710SRishi Srivatsavai {
200*4eaa4710SRishi Srivatsavai   register PORT_T* port;
201*4eaa4710SRishi Srivatsavai 
202*4eaa4710SRishi Srivatsavai   port = _stpapi_port_find (stpm, port_index);
203*4eaa4710SRishi Srivatsavai   if (! port) return;
204*4eaa4710SRishi Srivatsavai   if (port->portEnabled == enable) {/* nothing to do :) */
205*4eaa4710SRishi Srivatsavai     return;
206*4eaa4710SRishi Srivatsavai   }
207*4eaa4710SRishi Srivatsavai 
208*4eaa4710SRishi Srivatsavai   port->uptime = 0;
209*4eaa4710SRishi Srivatsavai   if (enable) { /* clear port statistics */
210*4eaa4710SRishi Srivatsavai     port->rx_cfg_bpdu_cnt =
211*4eaa4710SRishi Srivatsavai     port->rx_rstp_bpdu_cnt =
212*4eaa4710SRishi Srivatsavai     port->rx_tcn_bpdu_cnt = 0;
213*4eaa4710SRishi Srivatsavai   }
214*4eaa4710SRishi Srivatsavai 
215*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
216*4eaa4710SRishi Srivatsavai   if (port->edge->debug) {
217*4eaa4710SRishi Srivatsavai     stp_trace ("Port %s became '%s' adminEdge=%c",
218*4eaa4710SRishi Srivatsavai         port->port_name, enable ? "enable" : "disable",
219*4eaa4710SRishi Srivatsavai         port->adminEdge ? 'Y' : 'N');
220*4eaa4710SRishi Srivatsavai   }
221*4eaa4710SRishi Srivatsavai #endif
222*4eaa4710SRishi Srivatsavai 
223*4eaa4710SRishi Srivatsavai   port->adminEnable = enable;
224*4eaa4710SRishi Srivatsavai   STP_port_init (port, stpm, False);
225*4eaa4710SRishi Srivatsavai 
226*4eaa4710SRishi Srivatsavai   port->reselect = True;
227*4eaa4710SRishi Srivatsavai   port->selected = False;
228*4eaa4710SRishi Srivatsavai }
229*4eaa4710SRishi Srivatsavai 
230*4eaa4710SRishi Srivatsavai void
231*4eaa4710SRishi Srivatsavai STP_IN_init (STP_VECTORS_T *vectors)
232*4eaa4710SRishi Srivatsavai {
233*4eaa4710SRishi Srivatsavai   RSTP_INIT_CRITICAL_PATH_PROTECTIO;
234*4eaa4710SRishi Srivatsavai   stp_vectors = vectors;
235*4eaa4710SRishi Srivatsavai }
236*4eaa4710SRishi Srivatsavai 
237*4eaa4710SRishi Srivatsavai int
238*4eaa4710SRishi Srivatsavai STP_IN_stpm_get_cfg (IN int vlan_id, OUT UID_STP_CFG_T* uid_cfg)
239*4eaa4710SRishi Srivatsavai {
240*4eaa4710SRishi Srivatsavai   register STPM_T* this;
241*4eaa4710SRishi Srivatsavai 
242*4eaa4710SRishi Srivatsavai   uid_cfg->field_mask = 0;
243*4eaa4710SRishi Srivatsavai 
244*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
245*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
246*4eaa4710SRishi Srivatsavai 
247*4eaa4710SRishi Srivatsavai   if (!this) { /* it had not yet been created :( */
248*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
249*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
250*4eaa4710SRishi Srivatsavai   }
251*4eaa4710SRishi Srivatsavai 
252*4eaa4710SRishi Srivatsavai   if (this->admin_state != STP_DISABLED) {
253*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= BR_CFG_STATE;
254*4eaa4710SRishi Srivatsavai   }
255*4eaa4710SRishi Srivatsavai   uid_cfg->stp_enabled = this->admin_state;
256*4eaa4710SRishi Srivatsavai 
257*4eaa4710SRishi Srivatsavai   if (this->ForceVersion != 2) {
258*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= BR_CFG_FORCE_VER;
259*4eaa4710SRishi Srivatsavai   }
260*4eaa4710SRishi Srivatsavai   uid_cfg->force_version = this->ForceVersion;
261*4eaa4710SRishi Srivatsavai 
262*4eaa4710SRishi Srivatsavai   if (this->BrId.prio != DEF_BR_PRIO) {
263*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= BR_CFG_PRIO;
264*4eaa4710SRishi Srivatsavai   }
265*4eaa4710SRishi Srivatsavai   uid_cfg->bridge_priority = this->BrId.prio;
266*4eaa4710SRishi Srivatsavai 
267*4eaa4710SRishi Srivatsavai   if (this->BrTimes.MaxAge != DEF_BR_MAXAGE) {
268*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= BR_CFG_AGE;
269*4eaa4710SRishi Srivatsavai   }
270*4eaa4710SRishi Srivatsavai   uid_cfg->max_age = this->BrTimes.MaxAge;
271*4eaa4710SRishi Srivatsavai 
272*4eaa4710SRishi Srivatsavai   if (this->BrTimes.HelloTime != DEF_BR_HELLOT) {
273*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= BR_CFG_HELLO;
274*4eaa4710SRishi Srivatsavai   }
275*4eaa4710SRishi Srivatsavai   uid_cfg->hello_time = this->BrTimes.HelloTime;
276*4eaa4710SRishi Srivatsavai 
277*4eaa4710SRishi Srivatsavai   if (this->BrTimes.ForwardDelay != DEF_BR_FWDELAY) {
278*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= BR_CFG_DELAY;
279*4eaa4710SRishi Srivatsavai   }
280*4eaa4710SRishi Srivatsavai   uid_cfg->forward_delay = this->BrTimes.ForwardDelay;
281*4eaa4710SRishi Srivatsavai 
282*4eaa4710SRishi Srivatsavai   uid_cfg->hold_time = TxHoldCount;
283*4eaa4710SRishi Srivatsavai 
284*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
285*4eaa4710SRishi Srivatsavai   return 0;
286*4eaa4710SRishi Srivatsavai }
287*4eaa4710SRishi Srivatsavai 
288*4eaa4710SRishi Srivatsavai int
289*4eaa4710SRishi Srivatsavai STP_IN_port_get_cfg (int vlan_id, int port_index, UID_STP_PORT_CFG_T* uid_cfg)
290*4eaa4710SRishi Srivatsavai {
291*4eaa4710SRishi Srivatsavai   register STPM_T* this;
292*4eaa4710SRishi Srivatsavai   register PORT_T* port;
293*4eaa4710SRishi Srivatsavai 
294*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
295*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
296*4eaa4710SRishi Srivatsavai 
297*4eaa4710SRishi Srivatsavai   if (!this) { /* it had not yet been created :( */
298*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
299*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
300*4eaa4710SRishi Srivatsavai   }
301*4eaa4710SRishi Srivatsavai 
302*4eaa4710SRishi Srivatsavai   port = _stpapi_port_find (this, port_index);
303*4eaa4710SRishi Srivatsavai   if (! port) {/* port is absent in the stpm :( */
304*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
305*4eaa4710SRishi Srivatsavai     return STP_Port_Is_Absent_In_The_Vlan;
306*4eaa4710SRishi Srivatsavai   }
307*4eaa4710SRishi Srivatsavai 
308*4eaa4710SRishi Srivatsavai   uid_cfg->field_mask = 0;
309*4eaa4710SRishi Srivatsavai 
310*4eaa4710SRishi Srivatsavai   uid_cfg->port_priority = port->port_id >> 8;
311*4eaa4710SRishi Srivatsavai   if (uid_cfg->port_priority != DEF_PORT_PRIO)
312*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= PT_CFG_PRIO;
313*4eaa4710SRishi Srivatsavai 
314*4eaa4710SRishi Srivatsavai   uid_cfg->admin_port_path_cost = port->adminPCost;
315*4eaa4710SRishi Srivatsavai   if (uid_cfg->admin_port_path_cost != ADMIN_PORT_PATH_COST_AUTO)
316*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= PT_CFG_COST;
317*4eaa4710SRishi Srivatsavai 
318*4eaa4710SRishi Srivatsavai   uid_cfg->admin_point2point = port->adminPointToPointMac;
319*4eaa4710SRishi Srivatsavai   if (uid_cfg->admin_point2point != DEF_P2P)
320*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= PT_CFG_P2P;
321*4eaa4710SRishi Srivatsavai 
322*4eaa4710SRishi Srivatsavai   uid_cfg->admin_edge = port->adminEdge;
323*4eaa4710SRishi Srivatsavai   if (uid_cfg->admin_edge != DEF_ADMIN_EDGE)
324*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= PT_CFG_EDGE;
325*4eaa4710SRishi Srivatsavai 
326*4eaa4710SRishi Srivatsavai   uid_cfg->admin_non_stp = port->admin_non_stp;
327*4eaa4710SRishi Srivatsavai   if (uid_cfg->admin_non_stp != DEF_ADMIN_NON_STP)
328*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= PT_CFG_NON_STP;
329*4eaa4710SRishi Srivatsavai 
330*4eaa4710SRishi Srivatsavai   if (port->mcheck)
331*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask |= PT_CFG_MCHECK;
332*4eaa4710SRishi Srivatsavai 
333*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
334*4eaa4710SRishi Srivatsavai   return 0;
335*4eaa4710SRishi Srivatsavai }
336*4eaa4710SRishi Srivatsavai 
337*4eaa4710SRishi Srivatsavai int
338*4eaa4710SRishi Srivatsavai STP_IN_port_get_state (IN int vlan_id, INOUT UID_STP_PORT_STATE_T* entry)
339*4eaa4710SRishi Srivatsavai {
340*4eaa4710SRishi Srivatsavai   register STPM_T* this;
341*4eaa4710SRishi Srivatsavai   register PORT_T* port;
342*4eaa4710SRishi Srivatsavai 
343*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
344*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
345*4eaa4710SRishi Srivatsavai 
346*4eaa4710SRishi Srivatsavai   if (!this) { /* it had not yet been created :( */
347*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
348*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
349*4eaa4710SRishi Srivatsavai   }
350*4eaa4710SRishi Srivatsavai 
351*4eaa4710SRishi Srivatsavai   port = _stpapi_port_find (this, entry->port_no);
352*4eaa4710SRishi Srivatsavai   if (! port) {/* port is absent in the stpm :( */
353*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
354*4eaa4710SRishi Srivatsavai     return STP_Port_Is_Absent_In_The_Vlan;
355*4eaa4710SRishi Srivatsavai   }
356*4eaa4710SRishi Srivatsavai 
357*4eaa4710SRishi Srivatsavai   entry->port_id = port->port_id;
358*4eaa4710SRishi Srivatsavai   if (DisabledPort == port->role) {
359*4eaa4710SRishi Srivatsavai     entry->state = UID_PORT_DISABLED;
360*4eaa4710SRishi Srivatsavai   } else if (! port->forward && ! port->learn) {
361*4eaa4710SRishi Srivatsavai     entry->state = UID_PORT_DISCARDING;
362*4eaa4710SRishi Srivatsavai   } else if (! port->forward && port->learn) {
363*4eaa4710SRishi Srivatsavai     entry->state = UID_PORT_LEARNING;
364*4eaa4710SRishi Srivatsavai   } else {
365*4eaa4710SRishi Srivatsavai     entry->state = UID_PORT_FORWARDING;
366*4eaa4710SRishi Srivatsavai   }
367*4eaa4710SRishi Srivatsavai 
368*4eaa4710SRishi Srivatsavai   entry->uptime = port->uptime;
369*4eaa4710SRishi Srivatsavai   entry->path_cost = port->operPCost;
370*4eaa4710SRishi Srivatsavai   _conv_br_id_2_uid (&port->portPrio.root_bridge, &entry->designated_root);
371*4eaa4710SRishi Srivatsavai   entry->designated_cost = port->portPrio.root_path_cost;
372*4eaa4710SRishi Srivatsavai   _conv_br_id_2_uid (&port->portPrio.design_bridge, &entry->designated_bridge);
373*4eaa4710SRishi Srivatsavai   entry->designated_port = port->portPrio.design_port;
374*4eaa4710SRishi Srivatsavai 
375*4eaa4710SRishi Srivatsavai   switch (port->role) {
376*4eaa4710SRishi Srivatsavai     case DisabledPort:   entry->role = ' '; break;
377*4eaa4710SRishi Srivatsavai     case AlternatePort:  entry->role = 'A'; break;
378*4eaa4710SRishi Srivatsavai     case BackupPort:     entry->role = 'B'; break;
379*4eaa4710SRishi Srivatsavai     case RootPort:       entry->role = 'R'; break;
380*4eaa4710SRishi Srivatsavai     case DesignatedPort: entry->role = 'D'; break;
381*4eaa4710SRishi Srivatsavai     case NonStpPort:     entry->role = '-'; break;
382*4eaa4710SRishi Srivatsavai     default:             entry->role = '?'; break;
383*4eaa4710SRishi Srivatsavai   }
384*4eaa4710SRishi Srivatsavai 
385*4eaa4710SRishi Srivatsavai   if (DisabledPort == port->role || NonStpPort == port->role) {
386*4eaa4710SRishi Srivatsavai     (void) memset (&entry->designated_root, 0, sizeof (UID_BRIDGE_ID_T));
387*4eaa4710SRishi Srivatsavai     (void) memset (&entry->designated_bridge, 0, sizeof (UID_BRIDGE_ID_T));
388*4eaa4710SRishi Srivatsavai     entry->designated_cost = 0;
389*4eaa4710SRishi Srivatsavai     entry->designated_port = port->port_id;
390*4eaa4710SRishi Srivatsavai   }
391*4eaa4710SRishi Srivatsavai 
392*4eaa4710SRishi Srivatsavai   if (DisabledPort == port->role) {
393*4eaa4710SRishi Srivatsavai     entry->oper_point2point = (P2P_FORCE_FALSE == port->adminPointToPointMac) ? 0 : 1;
394*4eaa4710SRishi Srivatsavai     entry->oper_edge = port->adminEdge;
395*4eaa4710SRishi Srivatsavai     entry->oper_stp_neigb = 0;
396*4eaa4710SRishi Srivatsavai   } else {
397*4eaa4710SRishi Srivatsavai     entry->oper_point2point = port->operPointToPointMac ? 1 : 0;
398*4eaa4710SRishi Srivatsavai     entry->oper_edge = port->operEdge                   ? 1 : 0;
399*4eaa4710SRishi Srivatsavai     entry->oper_stp_neigb = port->sendRSTP              ? 0 : 1;
400*4eaa4710SRishi Srivatsavai   }
401*4eaa4710SRishi Srivatsavai   entry->oper_port_path_cost = port->operPCost;
402*4eaa4710SRishi Srivatsavai 
403*4eaa4710SRishi Srivatsavai   entry->rx_cfg_bpdu_cnt = port->rx_cfg_bpdu_cnt;
404*4eaa4710SRishi Srivatsavai   entry->rx_rstp_bpdu_cnt = port->rx_rstp_bpdu_cnt;
405*4eaa4710SRishi Srivatsavai   entry->rx_tcn_bpdu_cnt = port->rx_tcn_bpdu_cnt;
406*4eaa4710SRishi Srivatsavai 
407*4eaa4710SRishi Srivatsavai   entry->fdWhile =       port->fdWhile;      /* 17.15.1 */
408*4eaa4710SRishi Srivatsavai   entry->helloWhen =     port->helloWhen;    /* 17.15.2 */
409*4eaa4710SRishi Srivatsavai   entry->mdelayWhile =   port->mdelayWhile;  /* 17.15.3 */
410*4eaa4710SRishi Srivatsavai   entry->rbWhile =       port->rbWhile;      /* 17.15.4 */
411*4eaa4710SRishi Srivatsavai   entry->rcvdInfoWhile = port->rcvdInfoWhile;/* 17.15.5 */
412*4eaa4710SRishi Srivatsavai   entry->rrWhile =       port->rrWhile;      /* 17.15.6 */
413*4eaa4710SRishi Srivatsavai   entry->tcWhile =       port->tcWhile;      /* 17.15.7 */
414*4eaa4710SRishi Srivatsavai   entry->txCount =       port->txCount;      /* 17.18.40 */
415*4eaa4710SRishi Srivatsavai   entry->lnkWhile =      port->lnkWhile;
416*4eaa4710SRishi Srivatsavai 
417*4eaa4710SRishi Srivatsavai   entry->rcvdInfoWhile = port->rcvdInfoWhile;
418*4eaa4710SRishi Srivatsavai   entry->top_change_ack = port->tcAck;
419*4eaa4710SRishi Srivatsavai   entry->tc = port->tc;
420*4eaa4710SRishi Srivatsavai 
421*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
422*4eaa4710SRishi Srivatsavai   return 0;
423*4eaa4710SRishi Srivatsavai }
424*4eaa4710SRishi Srivatsavai 
425*4eaa4710SRishi Srivatsavai int
426*4eaa4710SRishi Srivatsavai STP_IN_stpm_get_state (IN int vlan_id, OUT UID_STP_STATE_T* entry)
427*4eaa4710SRishi Srivatsavai {
428*4eaa4710SRishi Srivatsavai   register STPM_T* this;
429*4eaa4710SRishi Srivatsavai 
430*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
431*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
432*4eaa4710SRishi Srivatsavai 
433*4eaa4710SRishi Srivatsavai   if (!this) { /* it had not yet been created :( */
434*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
435*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
436*4eaa4710SRishi Srivatsavai   }
437*4eaa4710SRishi Srivatsavai 
438*4eaa4710SRishi Srivatsavai   (void) strncpy (entry->vlan_name, this->name, NAME_LEN);
439*4eaa4710SRishi Srivatsavai   entry->vlan_id = this->vlan_id;
440*4eaa4710SRishi Srivatsavai   _conv_br_id_2_uid (&this->rootPrio.root_bridge, &entry->designated_root);
441*4eaa4710SRishi Srivatsavai   entry->root_path_cost = this->rootPrio.root_path_cost;
442*4eaa4710SRishi Srivatsavai   entry->root_port = this->rootPortId;
443*4eaa4710SRishi Srivatsavai   entry->max_age =       this->rootTimes.MaxAge;
444*4eaa4710SRishi Srivatsavai   entry->forward_delay = this->rootTimes.ForwardDelay;
445*4eaa4710SRishi Srivatsavai   entry->hello_time =    this->rootTimes.HelloTime;
446*4eaa4710SRishi Srivatsavai 
447*4eaa4710SRishi Srivatsavai   _conv_br_id_2_uid (&this->BrId, &entry->bridge_id);
448*4eaa4710SRishi Srivatsavai 
449*4eaa4710SRishi Srivatsavai   entry->stp_enabled = this->admin_state;
450*4eaa4710SRishi Srivatsavai 
451*4eaa4710SRishi Srivatsavai   entry->timeSince_Topo_Change = this->timeSince_Topo_Change;
452*4eaa4710SRishi Srivatsavai   entry->Topo_Change_Count = this->Topo_Change_Count;
453*4eaa4710SRishi Srivatsavai   entry->Topo_Change = this->Topo_Change;
454*4eaa4710SRishi Srivatsavai 
455*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
456*4eaa4710SRishi Srivatsavai   return 0;
457*4eaa4710SRishi Srivatsavai }
458*4eaa4710SRishi Srivatsavai 
459*4eaa4710SRishi Srivatsavai int
460*4eaa4710SRishi Srivatsavai STP_IN_stpm_get_name_by_vlan_id (int vlan_id, char* name, size_t buffsize)
461*4eaa4710SRishi Srivatsavai {
462*4eaa4710SRishi Srivatsavai   register STPM_T* stpm;
463*4eaa4710SRishi Srivatsavai   int iret = -1;
464*4eaa4710SRishi Srivatsavai 
465*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
466*4eaa4710SRishi Srivatsavai   for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) {
467*4eaa4710SRishi Srivatsavai     if (vlan_id ==  stpm->vlan_id) {
468*4eaa4710SRishi Srivatsavai       if (stpm->name)
469*4eaa4710SRishi Srivatsavai         (void) strncpy (name, stpm->name, buffsize);
470*4eaa4710SRishi Srivatsavai       else
471*4eaa4710SRishi Srivatsavai         (void) memset (name, 0, buffsize);
472*4eaa4710SRishi Srivatsavai       iret = 0;
473*4eaa4710SRishi Srivatsavai       break;
474*4eaa4710SRishi Srivatsavai     }
475*4eaa4710SRishi Srivatsavai   }
476*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
477*4eaa4710SRishi Srivatsavai   return iret;
478*4eaa4710SRishi Srivatsavai }
479*4eaa4710SRishi Srivatsavai 
480*4eaa4710SRishi Srivatsavai int /* call it, when link Up/Down */
481*4eaa4710SRishi Srivatsavai STP_IN_enable_port (int port_index, Bool enable)
482*4eaa4710SRishi Srivatsavai {
483*4eaa4710SRishi Srivatsavai   register STPM_T* stpm;
484*4eaa4710SRishi Srivatsavai 
485*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
486*4eaa4710SRishi Srivatsavai   if (! enable) {
487*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
488*4eaa4710SRishi Srivatsavai     stp_trace("%s (p%02d, all, %s, '%s')",
489*4eaa4710SRishi Srivatsavai         "clearFDB", (int) port_index, "this port", "disable port");
490*4eaa4710SRishi Srivatsavai #endif
491*4eaa4710SRishi Srivatsavai     STP_OUT_flush_lt (port_index, 0, LT_FLASH_ONLY_THE_PORT, "disable port");
492*4eaa4710SRishi Srivatsavai   }
493*4eaa4710SRishi Srivatsavai 
494*4eaa4710SRishi Srivatsavai   for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) {
495*4eaa4710SRishi Srivatsavai     if (STP_ENABLED != stpm->admin_state) continue;
496*4eaa4710SRishi Srivatsavai 
497*4eaa4710SRishi Srivatsavai     _stp_in_enable_port_on_stpm (stpm, port_index, enable);
498*4eaa4710SRishi Srivatsavai   	/* STP_stpm_update (stpm);*/
499*4eaa4710SRishi Srivatsavai   }
500*4eaa4710SRishi Srivatsavai 
501*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
502*4eaa4710SRishi Srivatsavai   return 0;
503*4eaa4710SRishi Srivatsavai }
504*4eaa4710SRishi Srivatsavai 
505*4eaa4710SRishi Srivatsavai int /* call it, when port speed has been changed, speed in Kb/s  */
506*4eaa4710SRishi Srivatsavai STP_IN_changed_port_speed (int port_index, long speed)
507*4eaa4710SRishi Srivatsavai {
508*4eaa4710SRishi Srivatsavai   register STPM_T* stpm;
509*4eaa4710SRishi Srivatsavai   register PORT_T* port;
510*4eaa4710SRishi Srivatsavai 
511*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
512*4eaa4710SRishi Srivatsavai   for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) {
513*4eaa4710SRishi Srivatsavai     if (STP_ENABLED != stpm->admin_state) continue;
514*4eaa4710SRishi Srivatsavai 
515*4eaa4710SRishi Srivatsavai     port = _stpapi_port_find (stpm, port_index);
516*4eaa4710SRishi Srivatsavai     if (! port) continue;
517*4eaa4710SRishi Srivatsavai     port->operSpeed = speed;
518*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
519*4eaa4710SRishi Srivatsavai     if (port->pcost->debug) {
520*4eaa4710SRishi Srivatsavai       stp_trace ("changed operSpeed=%lu", port->operSpeed);
521*4eaa4710SRishi Srivatsavai     }
522*4eaa4710SRishi Srivatsavai #endif
523*4eaa4710SRishi Srivatsavai 
524*4eaa4710SRishi Srivatsavai     port->reselect = True;
525*4eaa4710SRishi Srivatsavai     port->selected = False;
526*4eaa4710SRishi Srivatsavai   }
527*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
528*4eaa4710SRishi Srivatsavai   return 0;
529*4eaa4710SRishi Srivatsavai }
530*4eaa4710SRishi Srivatsavai 
531*4eaa4710SRishi Srivatsavai int /* call it, when port duplex mode has been changed  */
532*4eaa4710SRishi Srivatsavai STP_IN_changed_port_duplex (int port_index)
533*4eaa4710SRishi Srivatsavai {
534*4eaa4710SRishi Srivatsavai   register STPM_T* stpm;
535*4eaa4710SRishi Srivatsavai   register PORT_T* port;
536*4eaa4710SRishi Srivatsavai 
537*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
538*4eaa4710SRishi Srivatsavai   for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) {
539*4eaa4710SRishi Srivatsavai     if (STP_ENABLED != stpm->admin_state) continue;
540*4eaa4710SRishi Srivatsavai 
541*4eaa4710SRishi Srivatsavai     port = _stpapi_port_find (stpm, port_index);
542*4eaa4710SRishi Srivatsavai     if (! port) continue;
543*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
544*4eaa4710SRishi Srivatsavai     if (port->p2p->debug) {
545*4eaa4710SRishi Srivatsavai       stp_trace ("STP_IN_changed_port_duplex(%s)", port->port_name);
546*4eaa4710SRishi Srivatsavai     }
547*4eaa4710SRishi Srivatsavai #endif
548*4eaa4710SRishi Srivatsavai     port->p2p_recompute = True;
549*4eaa4710SRishi Srivatsavai     port->reselect = True;
550*4eaa4710SRishi Srivatsavai     port->selected = False;
551*4eaa4710SRishi Srivatsavai   }
552*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
553*4eaa4710SRishi Srivatsavai   return 0;
554*4eaa4710SRishi Srivatsavai }
555*4eaa4710SRishi Srivatsavai 
556*4eaa4710SRishi Srivatsavai int
557*4eaa4710SRishi Srivatsavai STP_IN_check_bpdu_header (BPDU_T* bpdu, size_t len)
558*4eaa4710SRishi Srivatsavai {
559*4eaa4710SRishi Srivatsavai   unsigned short len8023;
560*4eaa4710SRishi Srivatsavai 
561*4eaa4710SRishi Srivatsavai   /* LINTED: alignment */
562*4eaa4710SRishi Srivatsavai   len8023 = ntohs (*(unsigned short*) bpdu->eth.len8023);
563*4eaa4710SRishi Srivatsavai   if (len8023 > 1500) {/* big len8023 format :( */
564*4eaa4710SRishi Srivatsavai     return STP_Big_len8023_Format;
565*4eaa4710SRishi Srivatsavai   }
566*4eaa4710SRishi Srivatsavai 
567*4eaa4710SRishi Srivatsavai   if (len8023 < MIN_BPDU) { /* small len8023 format :( */
568*4eaa4710SRishi Srivatsavai     return STP_Small_len8023_Format;
569*4eaa4710SRishi Srivatsavai   }
570*4eaa4710SRishi Srivatsavai 
571*4eaa4710SRishi Srivatsavai   if (len8023 + 14 > len) { /* len8023 format gt len :( */
572*4eaa4710SRishi Srivatsavai     return STP_len8023_Format_Gt_Len;
573*4eaa4710SRishi Srivatsavai   }
574*4eaa4710SRishi Srivatsavai 
575*4eaa4710SRishi Srivatsavai   if (bpdu->eth.dsap != BPDU_L_SAP                 ||
576*4eaa4710SRishi Srivatsavai       bpdu->eth.ssap != BPDU_L_SAP                 ||
577*4eaa4710SRishi Srivatsavai       bpdu->eth.llc != LLC_UI) {
578*4eaa4710SRishi Srivatsavai     /* this is not a proper 802.3 pkt! :( */
579*4eaa4710SRishi Srivatsavai     return STP_Not_Proper_802_3_Packet;
580*4eaa4710SRishi Srivatsavai   }
581*4eaa4710SRishi Srivatsavai 
582*4eaa4710SRishi Srivatsavai   if (bpdu->hdr.protocol[0] || bpdu->hdr.protocol[1]) {
583*4eaa4710SRishi Srivatsavai     return STP_Invalid_Protocol;
584*4eaa4710SRishi Srivatsavai   }
585*4eaa4710SRishi Srivatsavai 
586*4eaa4710SRishi Srivatsavai #if 0
587*4eaa4710SRishi Srivatsavai   if (bpdu->hdr.version != BPDU_VERSION_ID) {
588*4eaa4710SRishi Srivatsavai     return STP_Invalid_Version;
589*4eaa4710SRishi Srivatsavai   }
590*4eaa4710SRishi Srivatsavai #endif
591*4eaa4710SRishi Srivatsavai   /* see also 9.3.4: think & TBD :( */
592*4eaa4710SRishi Srivatsavai   return 0;
593*4eaa4710SRishi Srivatsavai }
594*4eaa4710SRishi Srivatsavai 
595*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
596*4eaa4710SRishi Srivatsavai int dbg_rstp_deny = 0;
597*4eaa4710SRishi Srivatsavai #endif
598*4eaa4710SRishi Srivatsavai 
599*4eaa4710SRishi Srivatsavai 
600*4eaa4710SRishi Srivatsavai int
601*4eaa4710SRishi Srivatsavai STP_IN_rx_bpdu (int vlan_id, int port_index, BPDU_T* bpdu, size_t len)
602*4eaa4710SRishi Srivatsavai {
603*4eaa4710SRishi Srivatsavai   register PORT_T* port;
604*4eaa4710SRishi Srivatsavai   register STPM_T* this;
605*4eaa4710SRishi Srivatsavai   int              iret;
606*4eaa4710SRishi Srivatsavai 
607*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
608*4eaa4710SRishi Srivatsavai   if (1 == dbg_rstp_deny) {
609*4eaa4710SRishi Srivatsavai     return 0;
610*4eaa4710SRishi Srivatsavai   }
611*4eaa4710SRishi Srivatsavai #endif
612*4eaa4710SRishi Srivatsavai 
613*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
614*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
615*4eaa4710SRishi Srivatsavai   if (! this) { /*  the stpm had not yet been created :( */
616*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
617*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
618*4eaa4710SRishi Srivatsavai   }
619*4eaa4710SRishi Srivatsavai 
620*4eaa4710SRishi Srivatsavai   if (STP_DISABLED == this->admin_state) {/* the stpm had not yet been enabled :( */
621*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
622*4eaa4710SRishi Srivatsavai     return STP_Had_Not_Yet_Been_Enabled_On_The_Vlan;
623*4eaa4710SRishi Srivatsavai   }
624*4eaa4710SRishi Srivatsavai 
625*4eaa4710SRishi Srivatsavai   port = _stpapi_port_find (this, port_index);
626*4eaa4710SRishi Srivatsavai   if (! port) {/* port is absent in the stpm :( */
627*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
628*4eaa4710SRishi Srivatsavai     stp_trace ("RX bpdu vlan_id=%d port=%d port is absent in the stpm :(", (int) vlan_id, (int) port_index);
629*4eaa4710SRishi Srivatsavai #endif
630*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
631*4eaa4710SRishi Srivatsavai     return STP_Port_Is_Absent_In_The_Vlan;
632*4eaa4710SRishi Srivatsavai   }
633*4eaa4710SRishi Srivatsavai 
634*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
635*4eaa4710SRishi Srivatsavai   if (port->skip_rx > 0) {
636*4eaa4710SRishi Srivatsavai     if (1 == port->skip_rx)
637*4eaa4710SRishi Srivatsavai       stp_trace ("port %s stop rx skipping",
638*4eaa4710SRishi Srivatsavai                  port->port_name);
639*4eaa4710SRishi Srivatsavai     else
640*4eaa4710SRishi Srivatsavai       stp_trace ("port %s skip rx %d",
641*4eaa4710SRishi Srivatsavai                  port->port_name, port->skip_rx);
642*4eaa4710SRishi Srivatsavai     port->skip_rx--;
643*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
644*4eaa4710SRishi Srivatsavai     return STP_Nothing_To_Do;
645*4eaa4710SRishi Srivatsavai   }
646*4eaa4710SRishi Srivatsavai #endif
647*4eaa4710SRishi Srivatsavai 
648*4eaa4710SRishi Srivatsavai   if (port->operEdge && ! port->lnkWhile && port->portEnabled) {
649*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
650*4eaa4710SRishi Srivatsavai 	  if (port->topoch->debug) {
651*4eaa4710SRishi Srivatsavai     	stp_trace ("port %s tc=TRUE by operEdge", port->port_name);
652*4eaa4710SRishi Srivatsavai 	  }
653*4eaa4710SRishi Srivatsavai #endif
654*4eaa4710SRishi Srivatsavai     port->tc = True; /* IEEE 802.1y, 17.30 */
655*4eaa4710SRishi Srivatsavai   }
656*4eaa4710SRishi Srivatsavai 
657*4eaa4710SRishi Srivatsavai /* port link change indication will come later :( */
658*4eaa4710SRishi Srivatsavai   if (! port->portEnabled &&
659*4eaa4710SRishi Srivatsavai       STP_OUT_get_port_link_status (port->port_index)) {
660*4eaa4710SRishi Srivatsavai     _stp_in_enable_port_on_stpm (this, port->port_index, True);
661*4eaa4710SRishi Srivatsavai   }
662*4eaa4710SRishi Srivatsavai 
663*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
664*4eaa4710SRishi Srivatsavai   if (port->edge->debug && port->operEdge) {
665*4eaa4710SRishi Srivatsavai     stp_trace ("port %s not operEdge !", port->port_name);
666*4eaa4710SRishi Srivatsavai   }
667*4eaa4710SRishi Srivatsavai #endif
668*4eaa4710SRishi Srivatsavai 
669*4eaa4710SRishi Srivatsavai   port->operEdge = False;
670*4eaa4710SRishi Srivatsavai   port->wasInitBpdu = True;
671*4eaa4710SRishi Srivatsavai 
672*4eaa4710SRishi Srivatsavai   iret = STP_port_rx_bpdu (port, bpdu, len);
673*4eaa4710SRishi Srivatsavai   (void) STP_stpm_update (this);
674*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
675*4eaa4710SRishi Srivatsavai 
676*4eaa4710SRishi Srivatsavai   return iret;
677*4eaa4710SRishi Srivatsavai }
678*4eaa4710SRishi Srivatsavai 
679*4eaa4710SRishi Srivatsavai int
680*4eaa4710SRishi Srivatsavai STP_IN_one_second (void)
681*4eaa4710SRishi Srivatsavai {
682*4eaa4710SRishi Srivatsavai   register STPM_T* stpm;
683*4eaa4710SRishi Srivatsavai   register int     dbg_cnt = 0;
684*4eaa4710SRishi Srivatsavai 
685*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
686*4eaa4710SRishi Srivatsavai   for (stpm = STP_stpm_get_the_list (); stpm; stpm = stpm->next) {
687*4eaa4710SRishi Srivatsavai     if (STP_ENABLED == stpm->admin_state) {
688*4eaa4710SRishi Srivatsavai       /* stp_trace ("STP_IN_one_second vlan_id=%d", (int) stpm->vlan_id); */
689*4eaa4710SRishi Srivatsavai       STP_stpm_one_second (stpm);
690*4eaa4710SRishi Srivatsavai       dbg_cnt++;
691*4eaa4710SRishi Srivatsavai     }
692*4eaa4710SRishi Srivatsavai   }
693*4eaa4710SRishi Srivatsavai 
694*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
695*4eaa4710SRishi Srivatsavai 
696*4eaa4710SRishi Srivatsavai   return dbg_cnt;
697*4eaa4710SRishi Srivatsavai }
698*4eaa4710SRishi Srivatsavai 
699*4eaa4710SRishi Srivatsavai int
700*4eaa4710SRishi Srivatsavai STP_IN_stpm_set_cfg (IN int vlan_id,
701*4eaa4710SRishi Srivatsavai                      IN UID_STP_CFG_T* uid_cfg)
702*4eaa4710SRishi Srivatsavai {
703*4eaa4710SRishi Srivatsavai   int rc = 0, prev_prio, err_code;
704*4eaa4710SRishi Srivatsavai   Bool created_here, enabled_here;
705*4eaa4710SRishi Srivatsavai   register STPM_T* this;
706*4eaa4710SRishi Srivatsavai   UID_STP_CFG_T old;
707*4eaa4710SRishi Srivatsavai 
708*4eaa4710SRishi Srivatsavai   /* stp_trace ("STP_IN_stpm_set_cfg"); */
709*4eaa4710SRishi Srivatsavai   if (0 != STP_IN_stpm_get_cfg (vlan_id, &old)) {
710*4eaa4710SRishi Srivatsavai     STP_OUT_get_init_stpm_cfg (vlan_id, &old);
711*4eaa4710SRishi Srivatsavai   }
712*4eaa4710SRishi Srivatsavai 
713*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
714*4eaa4710SRishi Srivatsavai   if (BR_CFG_PRIO & uid_cfg->field_mask) {
715*4eaa4710SRishi Srivatsavai     old.bridge_priority = uid_cfg->bridge_priority;
716*4eaa4710SRishi Srivatsavai   }
717*4eaa4710SRishi Srivatsavai 
718*4eaa4710SRishi Srivatsavai   if (BR_CFG_AGE & uid_cfg->field_mask) {
719*4eaa4710SRishi Srivatsavai     old.max_age = uid_cfg->max_age;
720*4eaa4710SRishi Srivatsavai   }
721*4eaa4710SRishi Srivatsavai 
722*4eaa4710SRishi Srivatsavai   if (BR_CFG_HELLO & uid_cfg->field_mask) {
723*4eaa4710SRishi Srivatsavai     old.hello_time = uid_cfg->hello_time;
724*4eaa4710SRishi Srivatsavai   }
725*4eaa4710SRishi Srivatsavai 
726*4eaa4710SRishi Srivatsavai   if (BR_CFG_DELAY & uid_cfg->field_mask) {
727*4eaa4710SRishi Srivatsavai     old.forward_delay = uid_cfg->forward_delay;
728*4eaa4710SRishi Srivatsavai   }
729*4eaa4710SRishi Srivatsavai 
730*4eaa4710SRishi Srivatsavai   if (BR_CFG_FORCE_VER & uid_cfg->field_mask) {
731*4eaa4710SRishi Srivatsavai     old.force_version = uid_cfg->force_version;
732*4eaa4710SRishi Srivatsavai   }
733*4eaa4710SRishi Srivatsavai 
734*4eaa4710SRishi Srivatsavai   rc = _check_stpm_config (&old);
735*4eaa4710SRishi Srivatsavai   if (0 != rc) {
736*4eaa4710SRishi Srivatsavai     stp_trace ("_check_stpm_config failed %d", (int) rc);
737*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
738*4eaa4710SRishi Srivatsavai     return rc;
739*4eaa4710SRishi Srivatsavai   }
740*4eaa4710SRishi Srivatsavai 
741*4eaa4710SRishi Srivatsavai   if ((BR_CFG_STATE & uid_cfg->field_mask) &&
742*4eaa4710SRishi Srivatsavai       (STP_DISABLED == uid_cfg->stp_enabled)) {
743*4eaa4710SRishi Srivatsavai     rc = _stp_in_stpm_enable (vlan_id, uid_cfg->vlan_name, STP_DISABLED);
744*4eaa4710SRishi Srivatsavai     if (0 != rc) {
745*4eaa4710SRishi Srivatsavai       stp_trace ("can't disable rc=%d", (int) rc);
746*4eaa4710SRishi Srivatsavai       RSTP_CRITICAL_PATH_END;
747*4eaa4710SRishi Srivatsavai       return rc;
748*4eaa4710SRishi Srivatsavai     }
749*4eaa4710SRishi Srivatsavai     uid_cfg->field_mask &= ~BR_CFG_STATE;
750*4eaa4710SRishi Srivatsavai     if (! uid_cfg->field_mask)  {
751*4eaa4710SRishi Srivatsavai       RSTP_CRITICAL_PATH_END;
752*4eaa4710SRishi Srivatsavai       return 0;
753*4eaa4710SRishi Srivatsavai     }
754*4eaa4710SRishi Srivatsavai   }
755*4eaa4710SRishi Srivatsavai 
756*4eaa4710SRishi Srivatsavai   /* get current state */
757*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
758*4eaa4710SRishi Srivatsavai   created_here = False;
759*4eaa4710SRishi Srivatsavai   enabled_here = False;
760*4eaa4710SRishi Srivatsavai   if (! this) { /* it had not yet been created */
761*4eaa4710SRishi Srivatsavai     this = stp_in_stpm_create (vlan_id, uid_cfg->vlan_name, &err_code);
762*4eaa4710SRishi Srivatsavai     if (! this) {
763*4eaa4710SRishi Srivatsavai       RSTP_CRITICAL_PATH_END;
764*4eaa4710SRishi Srivatsavai       return err_code;
765*4eaa4710SRishi Srivatsavai     }
766*4eaa4710SRishi Srivatsavai   }
767*4eaa4710SRishi Srivatsavai 
768*4eaa4710SRishi Srivatsavai   prev_prio = this->BrId.prio;
769*4eaa4710SRishi Srivatsavai   this->BrId.prio = old.bridge_priority;
770*4eaa4710SRishi Srivatsavai   if (STP_ENABLED == this->admin_state) {
771*4eaa4710SRishi Srivatsavai     if (0 != STP_stpm_check_bridge_priority (this)) {
772*4eaa4710SRishi Srivatsavai       this->BrId.prio = prev_prio;
773*4eaa4710SRishi Srivatsavai       stp_trace ("%s", "STP_stpm_check_bridge_priority failed");
774*4eaa4710SRishi Srivatsavai       RSTP_CRITICAL_PATH_END;
775*4eaa4710SRishi Srivatsavai       return STP_Invalid_Bridge_Priority;
776*4eaa4710SRishi Srivatsavai     }
777*4eaa4710SRishi Srivatsavai   }
778*4eaa4710SRishi Srivatsavai 
779*4eaa4710SRishi Srivatsavai   this->BrTimes.MaxAge = old.max_age;
780*4eaa4710SRishi Srivatsavai   this->BrTimes.HelloTime = old.hello_time;
781*4eaa4710SRishi Srivatsavai   this->BrTimes.ForwardDelay = old.forward_delay;
782*4eaa4710SRishi Srivatsavai   this->ForceVersion = (PROTOCOL_VERSION_T) old.force_version;
783*4eaa4710SRishi Srivatsavai 
784*4eaa4710SRishi Srivatsavai   if ((BR_CFG_STATE & uid_cfg->field_mask) &&
785*4eaa4710SRishi Srivatsavai       STP_DISABLED != uid_cfg->stp_enabled &&
786*4eaa4710SRishi Srivatsavai       STP_DISABLED == this->admin_state) {
787*4eaa4710SRishi Srivatsavai     rc = _stp_in_stpm_enable (vlan_id, uid_cfg->vlan_name, uid_cfg->stp_enabled);
788*4eaa4710SRishi Srivatsavai     if (0 != rc) {
789*4eaa4710SRishi Srivatsavai       stp_trace ("%s", "cannot enable");
790*4eaa4710SRishi Srivatsavai       if (created_here) {
791*4eaa4710SRishi Srivatsavai         STP_stpm_delete (this);
792*4eaa4710SRishi Srivatsavai       }
793*4eaa4710SRishi Srivatsavai       RSTP_CRITICAL_PATH_END;
794*4eaa4710SRishi Srivatsavai       return rc;
795*4eaa4710SRishi Srivatsavai     }
796*4eaa4710SRishi Srivatsavai     enabled_here = True;
797*4eaa4710SRishi Srivatsavai   }
798*4eaa4710SRishi Srivatsavai 
799*4eaa4710SRishi Srivatsavai   if (! enabled_here && STP_DISABLED != this->admin_state) {
800*4eaa4710SRishi Srivatsavai     STP_stpm_update_after_bridge_management (this);
801*4eaa4710SRishi Srivatsavai   }
802*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
803*4eaa4710SRishi Srivatsavai   return 0;
804*4eaa4710SRishi Srivatsavai }
805*4eaa4710SRishi Srivatsavai 
806*4eaa4710SRishi Srivatsavai int
807*4eaa4710SRishi Srivatsavai STP_IN_port_set_cfg (IN int vlan_id, IN int port_index,
808*4eaa4710SRishi Srivatsavai     IN UID_STP_PORT_CFG_T* uid_cfg)
809*4eaa4710SRishi Srivatsavai {
810*4eaa4710SRishi Srivatsavai   register STPM_T* this;
811*4eaa4710SRishi Srivatsavai   register PORT_T* port;
812*4eaa4710SRishi Srivatsavai 
813*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
814*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
815*4eaa4710SRishi Srivatsavai   if (! this) { /* it had not yet been created :( */
816*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
817*4eaa4710SRishi Srivatsavai     stp_trace ("RSTP instance with tag %d hasn't been created\n", vlan_id);
818*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
819*4eaa4710SRishi Srivatsavai   }
820*4eaa4710SRishi Srivatsavai 
821*4eaa4710SRishi Srivatsavai   port = _stpapi_port_find (this, port_index);
822*4eaa4710SRishi Srivatsavai   if (! port) {/* port is absent in the stpm :( */
823*4eaa4710SRishi Srivatsavai     return STP_Port_Is_Absent_In_The_Vlan;
824*4eaa4710SRishi Srivatsavai   }
825*4eaa4710SRishi Srivatsavai 
826*4eaa4710SRishi Srivatsavai   if (PT_CFG_MCHECK & uid_cfg->field_mask) {
827*4eaa4710SRishi Srivatsavai     if (this->ForceVersion >= NORMAL_RSTP)
828*4eaa4710SRishi Srivatsavai       port->mcheck = True;
829*4eaa4710SRishi Srivatsavai   }
830*4eaa4710SRishi Srivatsavai 
831*4eaa4710SRishi Srivatsavai   if (PT_CFG_COST & uid_cfg->field_mask) {
832*4eaa4710SRishi Srivatsavai     port->adminPCost = uid_cfg->admin_port_path_cost;
833*4eaa4710SRishi Srivatsavai   }
834*4eaa4710SRishi Srivatsavai 
835*4eaa4710SRishi Srivatsavai   if (PT_CFG_PRIO & uid_cfg->field_mask) {
836*4eaa4710SRishi Srivatsavai     port->port_id = (uid_cfg->port_priority << 8) + port_index;
837*4eaa4710SRishi Srivatsavai   }
838*4eaa4710SRishi Srivatsavai 
839*4eaa4710SRishi Srivatsavai   if (PT_CFG_P2P & uid_cfg->field_mask) {
840*4eaa4710SRishi Srivatsavai     port->adminPointToPointMac = uid_cfg->admin_point2point;
841*4eaa4710SRishi Srivatsavai     port->p2p_recompute = True;
842*4eaa4710SRishi Srivatsavai   }
843*4eaa4710SRishi Srivatsavai 
844*4eaa4710SRishi Srivatsavai   if (PT_CFG_EDGE & uid_cfg->field_mask) {
845*4eaa4710SRishi Srivatsavai     port->adminEdge = uid_cfg->admin_edge;
846*4eaa4710SRishi Srivatsavai     port->operEdge = port->adminEdge;
847*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
848*4eaa4710SRishi Srivatsavai     if (port->edge->debug) {
849*4eaa4710SRishi Srivatsavai       stp_trace ("port %s is operEdge=%c in STP_IN_port_set_cfg",
850*4eaa4710SRishi Srivatsavai           port->port_name,
851*4eaa4710SRishi Srivatsavai           port->operEdge ? 'Y' : 'n');
852*4eaa4710SRishi Srivatsavai     }
853*4eaa4710SRishi Srivatsavai #endif
854*4eaa4710SRishi Srivatsavai   }
855*4eaa4710SRishi Srivatsavai 
856*4eaa4710SRishi Srivatsavai   if (PT_CFG_NON_STP & uid_cfg->field_mask) {
857*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
858*4eaa4710SRishi Srivatsavai     if (port->roletrns->debug && port->admin_non_stp != uid_cfg->admin_non_stp) {
859*4eaa4710SRishi Srivatsavai       stp_trace ("port %s is adminNonStp=%c in STP_IN_port_set_cfg",
860*4eaa4710SRishi Srivatsavai           port->port_name,
861*4eaa4710SRishi Srivatsavai           uid_cfg->admin_non_stp ? 'Y' : 'n');
862*4eaa4710SRishi Srivatsavai     }
863*4eaa4710SRishi Srivatsavai #endif
864*4eaa4710SRishi Srivatsavai     port->admin_non_stp = uid_cfg->admin_non_stp;
865*4eaa4710SRishi Srivatsavai   }
866*4eaa4710SRishi Srivatsavai 
867*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
868*4eaa4710SRishi Srivatsavai   if (PT_CFG_DBG_SKIP_RX & uid_cfg->field_mask) {
869*4eaa4710SRishi Srivatsavai     port->skip_rx = uid_cfg->skip_rx;
870*4eaa4710SRishi Srivatsavai   }
871*4eaa4710SRishi Srivatsavai 
872*4eaa4710SRishi Srivatsavai   if (PT_CFG_DBG_SKIP_TX & uid_cfg->field_mask) {
873*4eaa4710SRishi Srivatsavai     port->skip_tx = uid_cfg->skip_tx;
874*4eaa4710SRishi Srivatsavai   }
875*4eaa4710SRishi Srivatsavai 
876*4eaa4710SRishi Srivatsavai #endif
877*4eaa4710SRishi Srivatsavai 
878*4eaa4710SRishi Srivatsavai   port->reselect = True;
879*4eaa4710SRishi Srivatsavai   port->selected = False;
880*4eaa4710SRishi Srivatsavai 
881*4eaa4710SRishi Srivatsavai   (void) STP_stpm_update (this);
882*4eaa4710SRishi Srivatsavai 
883*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
884*4eaa4710SRishi Srivatsavai 
885*4eaa4710SRishi Srivatsavai   return 0;
886*4eaa4710SRishi Srivatsavai }
887*4eaa4710SRishi Srivatsavai 
888*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
889*4eaa4710SRishi Srivatsavai int
890*4eaa4710SRishi Srivatsavai 
891*4eaa4710SRishi Srivatsavai STP_IN_dbg_set_port_trace (char* mach_name, int enadis,
892*4eaa4710SRishi Srivatsavai     int vlan_id, int port_no)
893*4eaa4710SRishi Srivatsavai {
894*4eaa4710SRishi Srivatsavai   register STPM_T* this;
895*4eaa4710SRishi Srivatsavai   register PORT_T* port;
896*4eaa4710SRishi Srivatsavai   int rc;
897*4eaa4710SRishi Srivatsavai 
898*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
899*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
900*4eaa4710SRishi Srivatsavai   if (! this) { /* it had not yet been created :( */
901*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
902*4eaa4710SRishi Srivatsavai     stp_trace ("RSTP instance with tag %d hasn't been created\n", vlan_id);
903*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
904*4eaa4710SRishi Srivatsavai   }
905*4eaa4710SRishi Srivatsavai 
906*4eaa4710SRishi Srivatsavai   port = _stpapi_port_find (this, port_no);
907*4eaa4710SRishi Srivatsavai   if (! port) {/* port is absent in the stpm :( */
908*4eaa4710SRishi Srivatsavai     return STP_Port_Is_Absent_In_The_Vlan;
909*4eaa4710SRishi Srivatsavai   }
910*4eaa4710SRishi Srivatsavai   rc = STP_port_trace_state_machine (port, mach_name, enadis);
911*4eaa4710SRishi Srivatsavai 
912*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
913*4eaa4710SRishi Srivatsavai 
914*4eaa4710SRishi Srivatsavai   return rc;
915*4eaa4710SRishi Srivatsavai }
916*4eaa4710SRishi Srivatsavai 
917*4eaa4710SRishi Srivatsavai #endif
918*4eaa4710SRishi Srivatsavai 
919*4eaa4710SRishi Srivatsavai const char*
920*4eaa4710SRishi Srivatsavai STP_IN_get_error_explanation (int rstp_err_no)
921*4eaa4710SRishi Srivatsavai {
922*4eaa4710SRishi Srivatsavai #define CHOOSE(a) #a
923*4eaa4710SRishi Srivatsavai static char* rstp_error_names[] = RSTP_ERRORS;
924*4eaa4710SRishi Srivatsavai #undef CHOOSE
925*4eaa4710SRishi Srivatsavai   if (rstp_err_no < STP_OK) {
926*4eaa4710SRishi Srivatsavai     return "Too small error code :(";
927*4eaa4710SRishi Srivatsavai   }
928*4eaa4710SRishi Srivatsavai   if (rstp_err_no >= STP_LAST_DUMMY) {
929*4eaa4710SRishi Srivatsavai     return "Too big error code :(";
930*4eaa4710SRishi Srivatsavai   }
931*4eaa4710SRishi Srivatsavai 
932*4eaa4710SRishi Srivatsavai   return rstp_error_names[rstp_err_no];
933*4eaa4710SRishi Srivatsavai }
934*4eaa4710SRishi Srivatsavai 
935*4eaa4710SRishi Srivatsavai int
936*4eaa4710SRishi Srivatsavai STP_IN_port_add(int vlan_id, int port_index)
937*4eaa4710SRishi Srivatsavai {
938*4eaa4710SRishi Srivatsavai   STPM_T *this;
939*4eaa4710SRishi Srivatsavai   PORT_T *port;
940*4eaa4710SRishi Srivatsavai   int rc = STP_OK;
941*4eaa4710SRishi Srivatsavai 
942*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
943*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
944*4eaa4710SRishi Srivatsavai 
945*4eaa4710SRishi Srivatsavai   if (!this) { /* it had not yet been created :( */
946*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
947*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
948*4eaa4710SRishi Srivatsavai   }
949*4eaa4710SRishi Srivatsavai 
950*4eaa4710SRishi Srivatsavai   port = this->ports;
951*4eaa4710SRishi Srivatsavai 
952*4eaa4710SRishi Srivatsavai   if (! STP_port_create (this, port_index)) {
953*4eaa4710SRishi Srivatsavai     /* can't add port :( */
954*4eaa4710SRishi Srivatsavai     stp_trace ("can't create port %d", port_index);
955*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
956*4eaa4710SRishi Srivatsavai     return STP_Cannot_Create_Instance_For_Port;
957*4eaa4710SRishi Srivatsavai   }
958*4eaa4710SRishi Srivatsavai 
959*4eaa4710SRishi Srivatsavai   if (!port)
960*4eaa4710SRishi Srivatsavai     rc = STP_stpm_start (this);
961*4eaa4710SRishi Srivatsavai 
962*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
963*4eaa4710SRishi Srivatsavai 
964*4eaa4710SRishi Srivatsavai   return rc;
965*4eaa4710SRishi Srivatsavai }
966*4eaa4710SRishi Srivatsavai 
967*4eaa4710SRishi Srivatsavai int
968*4eaa4710SRishi Srivatsavai STP_IN_port_remove(int vlan_id, int port_index)
969*4eaa4710SRishi Srivatsavai {
970*4eaa4710SRishi Srivatsavai   STPM_T *this;
971*4eaa4710SRishi Srivatsavai   PORT_T *port;
972*4eaa4710SRishi Srivatsavai 
973*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
974*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
975*4eaa4710SRishi Srivatsavai 
976*4eaa4710SRishi Srivatsavai   if (!this) { /* it had not yet been created :( */
977*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
978*4eaa4710SRishi Srivatsavai     return STP_Vlan_Had_Not_Yet_Been_Created;
979*4eaa4710SRishi Srivatsavai   }
980*4eaa4710SRishi Srivatsavai 
981*4eaa4710SRishi Srivatsavai   port = _stpapi_port_find (this, port_index);
982*4eaa4710SRishi Srivatsavai   if (! port) {/* port is absent in the stpm :( */
983*4eaa4710SRishi Srivatsavai     RSTP_CRITICAL_PATH_END;
984*4eaa4710SRishi Srivatsavai     return STP_Port_Is_Absent_In_The_Vlan;
985*4eaa4710SRishi Srivatsavai   }
986*4eaa4710SRishi Srivatsavai 
987*4eaa4710SRishi Srivatsavai   STP_port_delete (port);
988*4eaa4710SRishi Srivatsavai 
989*4eaa4710SRishi Srivatsavai   if (!this->ports)
990*4eaa4710SRishi Srivatsavai     STP_stpm_stop (this);
991*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
992*4eaa4710SRishi Srivatsavai 
993*4eaa4710SRishi Srivatsavai   return STP_OK;
994*4eaa4710SRishi Srivatsavai }
995*4eaa4710SRishi Srivatsavai 
996*4eaa4710SRishi Srivatsavai void
997*4eaa4710SRishi Srivatsavai STP_IN_get_bridge_id(int vlan_id, unsigned short *priority, unsigned char *mac)
998*4eaa4710SRishi Srivatsavai {
999*4eaa4710SRishi Srivatsavai   STPM_T *this;
1000*4eaa4710SRishi Srivatsavai 
1001*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_START;
1002*4eaa4710SRishi Srivatsavai   this = stpapi_stpm_find (vlan_id);
1003*4eaa4710SRishi Srivatsavai   *priority = this->BrId.prio;
1004*4eaa4710SRishi Srivatsavai   (void) memcpy(mac, this->BrId.addr, 6);
1005*4eaa4710SRishi Srivatsavai   RSTP_CRITICAL_PATH_END;
1006*4eaa4710SRishi Srivatsavai }
1007*4eaa4710SRishi Srivatsavai 
1008*4eaa4710SRishi Srivatsavai const char *
1009*4eaa4710SRishi Srivatsavai STP_IN_state2str(RSTP_PORT_STATE state)
1010*4eaa4710SRishi Srivatsavai {
1011*4eaa4710SRishi Srivatsavai 	switch (state) {
1012*4eaa4710SRishi Srivatsavai 	case UID_PORT_DISABLED:
1013*4eaa4710SRishi Srivatsavai 		return ("disabled");
1014*4eaa4710SRishi Srivatsavai 	case UID_PORT_DISCARDING:
1015*4eaa4710SRishi Srivatsavai 		return ("discarding");
1016*4eaa4710SRishi Srivatsavai 	case UID_PORT_LEARNING:
1017*4eaa4710SRishi Srivatsavai 		return ("learning");
1018*4eaa4710SRishi Srivatsavai 	case UID_PORT_FORWARDING:
1019*4eaa4710SRishi Srivatsavai 		return ("forwarding");
1020*4eaa4710SRishi Srivatsavai 	case UID_PORT_NON_STP:
1021*4eaa4710SRishi Srivatsavai 		return ("non-stp");
1022*4eaa4710SRishi Srivatsavai 	case UID_PORT_BADSDU:		/* synthetic state used by daemon */
1023*4eaa4710SRishi Srivatsavai 		return ("bad-mtu");
1024*4eaa4710SRishi Srivatsavai 	}
1025*4eaa4710SRishi Srivatsavai 	return ("unknown");
1026*4eaa4710SRishi Srivatsavai }
1027