1 /************************************************************************
2 * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
3 * Copyright (C) 2001-2003 Optical Access
6 * This file is part of RSTP library.
8 * RSTP library is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by the
10 * Free Software Foundation; version 2.1
12 * RSTP library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
15 * General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with RSTP library; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 **********************************************************************/
23 /* STP PORT instance : 17.18, 17.15 */
29 /* #include "rolesel.h" */
40 #include "stp_to.h" /* for STP_OUT_get_port_name & STP_OUT_get_port_link_status */
43 STP_port_create (STPM_T
* stpm
, int port_index
)
46 UID_STP_PORT_CFG_T port_cfg
;
48 unsigned short port_prio
;
50 /* check, if the port has just been added */
51 for (this = stpm
->ports
; this; this = this->next
) {
52 if (this->port_index
== port_index
) {
57 STP_NEW_IN_LIST(this, PORT_T
, stpm
->ports
, "port create");
60 this->machines
= NULL
;
61 this->port_index
= port_index
;
62 this->port_name
= strdup (STP_OUT_get_port_name (port_index
));
65 STP_OUT_get_init_port_cfg (stpm
->vlan_id
, port_index
, &port_cfg
);
66 port_prio
= port_cfg
.port_priority
;
67 this->admin_non_stp
= port_cfg
.admin_non_stp
;
68 this->adminEdge
= port_cfg
.admin_edge
;
69 this->adminPCost
= port_cfg
.admin_port_path_cost
;
70 this->adminPointToPointMac
= port_cfg
.admin_point2point
;
72 this->LinkDelay
= DEF_LINK_DELAY
;
73 this->port_id
= (port_prio
<< 8) + port_index
;
76 this->timers
[iii
++] = &this->fdWhile
;
77 this->timers
[iii
++] = &this->helloWhen
;
78 this->timers
[iii
++] = &this->mdelayWhile
;
79 this->timers
[iii
++] = &this->rbWhile
;
80 this->timers
[iii
++] = &this->rcvdInfoWhile
;
81 this->timers
[iii
++] = &this->rrWhile
;
82 this->timers
[iii
++] = &this->tcWhile
;
83 this->timers
[iii
++] = &this->txCount
;
84 this->timers
[iii
++] = &this->lnkWhile
;
86 /* create and bind port state machines */
87 STP_STATE_MACH_IN_LIST(topoch
);
89 STP_STATE_MACH_IN_LIST(migrate
);
91 STP_STATE_MACH_IN_LIST(p2p
);
93 STP_STATE_MACH_IN_LIST(edge
);
95 STP_STATE_MACH_IN_LIST(pcost
)
97 STP_STATE_MACH_IN_LIST(info
);
99 STP_STATE_MACH_IN_LIST(roletrns
);
101 STP_STATE_MACH_IN_LIST(sttrans
);
103 STP_STATE_MACH_IN_LIST(transmit
);
108 this->roletrns
->ignoreHop2State
= 14; /* DESIGNATED_PORT; */
109 this->info
->ignoreHop2State
= 3; /* CURRENT */
110 this->transmit
->ignoreHop2State
= 3; /* IDLE */
111 this->edge
->ignoreHop2State
= 0; /* DISABLED; */
115 this->info
->debug
= 1;
116 this->pcost
->debug
= 1;
117 this->p2p
->debug
= 1;
118 this->edge
->debug
= 1;
119 this->migrate
->debug
= 1;
120 this->sttrans
->debug
= 1;
121 this->topoch
->debug
= 1;
122 this->roletrns
->debug
= 1;
124 this->sttrans
->debug
= 1;
131 STP_port_init (PORT_T
* this, STPM_T
* stpm
, Bool check_link
)
134 this->adminEnable
= STP_OUT_get_port_link_status (this->port_index
);
135 STP_VECT_create (&this->designPrio
,
141 STP_copy_times (&this->designTimes
, &stpm
->rootTimes
);
149 this->rcvdInfoWhile
=
154 this->msgPortRole
= RSTP_PORT_ROLE_UNKN
;
155 this->selectedRole
= DisabledPort
;
156 this->sendRSTP
= True
;
157 this->operSpeed
= STP_OUT_get_port_oper_speed (this->port_index
);
158 this->p2p_recompute
= True
;
162 STP_port_delete (PORT_T
* this)
165 register PORT_T
* prev
;
166 register PORT_T
* tmp
;
167 register STATE_MACH_T
* stater
;
172 free (this->port_name
);
173 for (stater
= this->machines
; stater
; ) {
174 pv
= (void*) stater
->next
;
175 STP_state_mach_delete (stater
);
176 stater
= (STATE_MACH_T
*) pv
;
180 for (tmp
= stpm
->ports
; tmp
; tmp
= tmp
->next
) {
181 if (tmp
->port_index
== this->port_index
) {
183 prev
->next
= this->next
;
185 stpm
->ports
= this->next
;
187 STP_FREE(this, "stp instance");
195 STP_port_rx_bpdu (PORT_T
* this, BPDU_T
* bpdu
, size_t len
)
197 STP_info_rx_bpdu (this, bpdu
, len
);
203 int STP_port_trace_state_machine (PORT_T
* this, char* mach_name
, int enadis
, int vlan_id
)
205 register struct state_mach_t
* stater
;
207 for (stater
= this->machines
; stater
; stater
= stater
->next
) {
208 if (! strcmp (mach_name
, "all") || ! strcmp (mach_name
, stater
->name
)) {
209 /* if (stater->debug != enadis) */
211 stp_trace ("port %s on %s trace %-8s (was %s) now %s",
212 this->port_name
, this->owner
->name
,
214 stater
->debug
? " enabled" :"disabled",
215 enadis
? " enabled" :"disabled");
217 stater
->debug
= enadis
;
224 void STP_port_trace_flags (char* title
, PORT_T
* this)
226 #if 0 /* it may be opened for more deep debugging */
227 unsigned long flag
= 0L;
229 if (this->reRoot
) flag
|= 0x000001L
;
230 if (this->sync
) flag
|= 0x000002L
;
231 if (this->synced
) flag
|= 0x000004L
;
233 if (this->proposed
) flag
|= 0x000010L
;
234 if (this->proposing
) flag
|= 0x000020L
;
235 if (this->agreed
) flag
|= 0x000040L
;
236 if (this->updtInfo
) flag
|= 0x000080L
;
238 if (this->operEdge
) flag
|= 0x000100L
;
239 stp_trace (" %-12s: flags=0X%04lx port=%s", title
, flag
, this->port_name
);