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 */
42 #include "stp_to.h" /* for STP_OUT_get_port_name & STP_OUT_get_port_link_status */
43 #include "rstp_bridge.h"
45 Bool
portEnabled(PORT_T
*self
)
47 if (self
->adminEnable
&& self
->macOperational
)
53 PORT_T
* STP_port_create (STPM_T
* stpm
, int port_index
)
56 UID_STP_PORT_CFG_T port_cfg
;
58 unsigned short port_prio
;
60 /* check, if the port has just been added */
61 for (self
= stpm
->ports
; self
; self
= self
->next
) {
62 if (self
->port_index
== port_index
) {
67 STP_NEW_IN_LIST(self
, PORT_T
, stpm
->ports
, "port create");
70 self
->machines
= NULL
;
71 self
->port_index
= port_index
;
72 self
->port_name
= strdup (STP_OUT_get_port_name (self
->owner
->rstp
, port_index
));
75 STP_OUT_get_init_port_cfg (stpm
->rstp
, stpm
->vlan_id
, port_index
, &port_cfg
);
77 STP_OUT_get_init_port_cfg (stpm
->vlan_id
, port_index
, &port_cfg
);
79 port_prio
= port_cfg
.port_priority
;
80 self
->admin_non_stp
= port_cfg
.admin_non_stp
;
81 self
->adminEdge
= port_cfg
.admin_edge
;
83 self
->autoEdge
= port_cfg
.auto_edge
;
85 self
->adminPCost
= port_cfg
.admin_port_path_cost
;
86 self
->adminPointToPointMac
= port_cfg
.admin_point2point
;
88 self
->LinkDelay
= DEF_LINK_DELAY
;
89 self
->port_id
= (port_prio
<< 8) + port_index
;
92 self
->timers
[iii
++] = &self
->fdWhile
;
93 self
->timers
[iii
++] = &self
->helloWhen
;
94 self
->timers
[iii
++] = &self
->mdelayWhile
;
95 self
->timers
[iii
++] = &self
->rbWhile
;
96 self
->timers
[iii
++] = &self
->rcvdInfoWhile
;
97 self
->timers
[iii
++] = &self
->rrWhile
;
98 self
->timers
[iii
++] = &self
->tcWhile
;
99 self
->timers
[iii
++] = &self
->txCount
;
100 self
->timers
[iii
++] = &self
->lnkWhile
;
102 /* create and bind port state machines */
103 STP_STATE_MACH_IN_LIST(topoch
);
105 STP_STATE_MACH_IN_LIST(migrate
);
107 STP_STATE_MACH_IN_LIST(p2p
);
109 #if 0 /* leu: replaced by brdec */
110 STP_STATE_MACH_IN_LIST(edge
);
113 STP_STATE_MACH_IN_LIST(pcost
)
115 STP_STATE_MACH_IN_LIST(info
);
117 STP_STATE_MACH_IN_LIST(roletrns
);
119 STP_STATE_MACH_IN_LIST(sttrans
);
121 STP_STATE_MACH_IN_LIST(transmit
);
123 STP_STATE_MACH_IN_LIST(portrec
); /* kd: new */
125 STP_STATE_MACH_IN_LIST(brdec
); /* kd: new */
129 self
->roletrns
->ignoreHop2State
= 14; /* DESIGNATED_PORT; */
130 self
->info
->ignoreHop2State
= 3; /* CURRENT */
131 self
->transmit
->ignoreHop2State
= 3; /* IDLE */
132 self
->edge
->ignoreHop2State
= 0; /* DISABLED; */
136 self
->info
->debug
= 1;
137 self
->pcost
->debug
= 1;
138 self
->p2p
->debug
= 1;
139 self
->edge
->debug
= 1;
140 self
->migrate
->debug
= 1;
141 self
->sttrans
->debug
= 1;
142 self
->topoch
->debug
= 1;
143 self
->roletrns
->debug
= 1;
144 self
->portrec
->debug
= 1;
145 self
->brdec
->debug
= 1;
146 self
->sttrans
->debug
= 1;
153 void STP_port_init (PORT_T
* self
, STPM_T
* stpm
, Bool check_link
)
156 self
->adminEnable
= STP_OUT_get_port_link_status (stpm
->rstp
, self
->port_index
);
157 STP_VECT_create (&self
->designPrio
,
163 STP_copy_times (&self
->designTimes
, &stpm
->rootTimes
);
171 self
->rcvdInfoWhile
=
176 self
->msgPortRole
= RSTP_PORT_ROLE_UNKN
;
177 self
->selectedRole
= DisabledPort
;
178 self
->sendRSTP
= True
;
179 self
->operSpeed
= STP_OUT_get_port_oper_speed (self
->owner
->rstp
, self
->port_index
);
180 self
->p2p_recompute
= True
;
183 void STP_port_delete (PORT_T
* self
)
186 register PORT_T
* prev
;
187 register PORT_T
* tmp
;
188 register STATE_MACH_T
* stater
;
193 free (self
->port_name
);
194 for (stater
= self
->machines
; stater
; ) {
195 pv
= (void*) stater
->next
;
196 STP_state_mach_delete (stater
);
197 stater
= (STATE_MACH_T
*) pv
;
201 for (tmp
= stpm
->ports
; tmp
; tmp
= tmp
->next
) {
202 if (tmp
->port_index
== self
->port_index
) {
204 prev
->next
= self
->next
;
206 stpm
->ports
= self
->next
;
208 STP_FREE(self
, "stp instance");
215 int STP_port_rx_bpdu (PORT_T
* self
, BPDU_T
* bpdu
, size_t len
)
217 STP_info_rx_bpdu (self
, bpdu
, len
);
222 int STP_port_trace_state_machine (PORT_T
* self
, char* mach_name
, int enadis
, int vlan_id
)
224 register struct state_mach_t
* stater
;
226 for (stater
= self
->machines
; stater
; stater
= stater
->next
) {
227 if (! strcmp (mach_name
, "all") || ! strcmp (mach_name
, stater
->name
)) {
229 stp_trace ("port %s on %s trace %-8s (was %s) now %s",
230 self
->port_name
, self
->owner
->name
,
232 stater
->debug
? " enabled" :"disabled",
233 enadis
? " enabled" :"disabled");
234 stater
->debug
= enadis
;
240 void STP_port_trace_flags (char* title
, PORT_T
* self
)
242 /* it may be opened for more deep debugging */
244 unsigned long flag
= 0L;
246 if (self
->reRoot
) flag
|= 0x000001L
;
247 if (self
->sync
) flag
|= 0x000002L
;
248 if (self
->synced
) flag
|= 0x000004L
;
250 if (self
->proposed
) flag
|= 0x000010L
;
251 if (self
->proposing
) flag
|= 0x000020L
;
252 if (self
->agreed
) flag
|= 0x000040L
;
253 if (self
->updtInfo
) flag
|= 0x000080L
;
255 if (self
->operEdge
) flag
|= 0x000100L
;
256 stp_trace (" %-12s: flags=0x%04lx port=%s", title
, flag
, self
->port_name
);