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 */
45 STP_port_create (STPM_T
* stpm
, int port_index
)
48 UID_STP_PORT_CFG_T port_cfg
;
50 unsigned short port_prio
;
52 /* check, if the port has just been added */
53 for (this = stpm
->ports
; this; this = this->next
) {
54 if (this->port_index
== port_index
) {
59 STP_NEW_IN_LIST(this, PORT_T
, stpm
->ports
, "port create");
62 this->machines
= NULL
;
63 this->port_index
= port_index
;
64 this->port_name
= strdup (STP_OUT_get_port_name (port_index
));
67 STP_OUT_get_init_port_cfg (stpm
->vlan_id
, port_index
, &port_cfg
);
68 port_prio
= port_cfg
.port_priority
;
69 this->admin_non_stp
= port_cfg
.admin_non_stp
;
70 this->adminEdge
= port_cfg
.admin_edge
;
71 this->adminPCost
= port_cfg
.admin_port_path_cost
;
72 this->adminPointToPointMac
= port_cfg
.admin_point2point
;
74 this->LinkDelay
= DEF_LINK_DELAY
;
75 this->port_id
= (port_prio
<< 8) + port_index
;
78 this->timers
[iii
++] = &this->fdWhile
;
79 this->timers
[iii
++] = &this->helloWhen
;
80 this->timers
[iii
++] = &this->mdelayWhile
;
81 this->timers
[iii
++] = &this->rbWhile
;
82 this->timers
[iii
++] = &this->rcvdInfoWhile
;
83 this->timers
[iii
++] = &this->rrWhile
;
84 this->timers
[iii
++] = &this->tcWhile
;
85 this->timers
[iii
++] = &this->txCount
;
86 this->timers
[iii
++] = &this->lnkWhile
;
88 /* create and bind port state machines */
89 STP_STATE_MACH_IN_LIST(topoch
);
91 STP_STATE_MACH_IN_LIST(migrate
);
93 STP_STATE_MACH_IN_LIST(p2p
);
95 STP_STATE_MACH_IN_LIST(edge
);
97 STP_STATE_MACH_IN_LIST(pcost
)
99 STP_STATE_MACH_IN_LIST(info
);
101 STP_STATE_MACH_IN_LIST(roletrns
);
103 STP_STATE_MACH_IN_LIST(sttrans
);
105 STP_STATE_MACH_IN_LIST(transmit
);
110 this->roletrns
->ignoreHop2State
= 14; /* DESIGNATED_PORT; */
111 this->info
->ignoreHop2State
= 3; /* CURRENT */
112 this->transmit
->ignoreHop2State
= 3; /* IDLE */
113 this->edge
->ignoreHop2State
= 0; /* DISABLED; */
117 this->info
->debug
= 1;
118 this->pcost
->debug
= 1;
119 this->p2p
->debug
= 1;
120 this->edge
->debug
= 1;
121 this->migrate
->debug
= 1;
122 this->sttrans
->debug
= 1;
123 this->topoch
->debug
= 1;
124 this->roletrns
->debug
= 1;
126 this->sttrans
->debug
= 1;
133 STP_port_init (PORT_T
* this, STPM_T
* stpm
, Bool check_link
)
136 this->adminEnable
= STP_OUT_get_port_link_status (this->port_index
);
137 STP_VECT_create (&this->designPrio
,
143 STP_copy_times (&this->designTimes
, &stpm
->rootTimes
);
151 this->rcvdInfoWhile
=
156 this->msgPortRole
= RSTP_PORT_ROLE_UNKN
;
157 this->selectedRole
= DisabledPort
;
158 this->sendRSTP
= True
;
159 this->operSpeed
= STP_OUT_get_port_oper_speed (this->port_index
);
160 this->p2p_recompute
= True
;
164 STP_port_delete (PORT_T
* this)
167 register PORT_T
* prev
;
168 register PORT_T
* tmp
;
169 register STATE_MACH_T
* stater
;
174 free (this->port_name
);
175 for (stater
= this->machines
; stater
; ) {
176 pv
= (void*) stater
->next
;
177 STP_state_mach_delete (stater
);
178 stater
= (STATE_MACH_T
*) pv
;
182 for (tmp
= stpm
->ports
; tmp
; tmp
= tmp
->next
) {
183 if (tmp
->port_index
== this->port_index
) {
185 prev
->next
= this->next
;
187 stpm
->ports
= this->next
;
189 STP_FREE(this, "stp instance");
197 STP_port_rx_bpdu (PORT_T
* this, BPDU_T
* bpdu
, size_t len
)
199 STP_info_rx_bpdu (this, bpdu
, len
);
205 int STP_port_trace_state_machine (PORT_T
* this, char* mach_name
, int enadis
)
207 STATE_MACH_T
*stater
;
210 for (stater
= this->machines
; stater
; stater
= stater
->next
) {
211 if (! strcmp (mach_name
, "all") || ! strcmp (mach_name
, stater
->name
)) {
212 if (stater
->debug
!= enadis
)
214 stp_trace ("port %s on %s trace %-8s (was %s) now %s",
215 this->port_name
, this->owner
->name
,
217 stater
->debug
? " enabled" :"disabled",
218 enadis
? " enabled" :"disabled");
220 stater
->debug
= enadis
;
226 stp_trace("port %s no such state machine as '%s'", this->port_name
,
228 return STP_No_Such_State_Machine
;
234 void STP_port_trace_flags (char* title
, PORT_T
* this)
236 unsigned long flag
= 0L;
238 if (!port_trace_flags
) return;
240 if (this->reRoot
) flag
|= 0x000001L
;
241 if (this->sync
) flag
|= 0x000002L
;
242 if (this->synced
) flag
|= 0x000004L
;
244 if (this->proposed
) flag
|= 0x000010L
;
245 if (this->proposing
) flag
|= 0x000020L
;
246 if (this->agreed
) flag
|= 0x000040L
;
247 if (this->updtInfo
) flag
|= 0x000080L
;
249 if (this->operEdge
) flag
|= 0x000100L
;
250 stp_trace (" %-12s: flags=0x%04lx fdWhile=%d port=%s", title
, flag
, this->fdWhile
, this->port_name
);