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