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 /* Port Transmit state machine : 17.27 */
24*4eaa4710SRishi Srivatsavai
25*4eaa4710SRishi Srivatsavai #include "base.h"
26*4eaa4710SRishi Srivatsavai #include "stpm.h"
27*4eaa4710SRishi Srivatsavai #include "stp_to.h" /* for STP_OUT_get_port_mac & STP_OUT_tx_bpdu */
28*4eaa4710SRishi Srivatsavai
29*4eaa4710SRishi Srivatsavai #define BPDU_LEN8023_OFF 12
30*4eaa4710SRishi Srivatsavai
31*4eaa4710SRishi Srivatsavai #define STATES { \
32*4eaa4710SRishi Srivatsavai CHOOSE(TRANSMIT_INIT), \
33*4eaa4710SRishi Srivatsavai CHOOSE(TRANSMIT_PERIODIC), \
34*4eaa4710SRishi Srivatsavai CHOOSE(IDLE), \
35*4eaa4710SRishi Srivatsavai CHOOSE(TRANSMIT_CONFIG), \
36*4eaa4710SRishi Srivatsavai CHOOSE(TRANSMIT_TCN), \
37*4eaa4710SRishi Srivatsavai CHOOSE(TRANSMIT_RSTP) \
38*4eaa4710SRishi Srivatsavai }
39*4eaa4710SRishi Srivatsavai
40*4eaa4710SRishi Srivatsavai #define GET_STATE_NAME STP_transmit_get_state_name
41*4eaa4710SRishi Srivatsavai #include "choose.h"
42*4eaa4710SRishi Srivatsavai
43*4eaa4710SRishi Srivatsavai #define MIN_FRAME_LENGTH 64
44*4eaa4710SRishi Srivatsavai
45*4eaa4710SRishi Srivatsavai
46*4eaa4710SRishi Srivatsavai typedef struct tx_tcn_bpdu_t {
47*4eaa4710SRishi Srivatsavai MAC_HEADER_T mac;
48*4eaa4710SRishi Srivatsavai ETH_HEADER_T eth;
49*4eaa4710SRishi Srivatsavai BPDU_HEADER_T hdr;
50*4eaa4710SRishi Srivatsavai } TCN_BPDU_T;
51*4eaa4710SRishi Srivatsavai
52*4eaa4710SRishi Srivatsavai typedef struct tx_stp_bpdu_t {
53*4eaa4710SRishi Srivatsavai MAC_HEADER_T mac;
54*4eaa4710SRishi Srivatsavai ETH_HEADER_T eth;
55*4eaa4710SRishi Srivatsavai BPDU_HEADER_T hdr;
56*4eaa4710SRishi Srivatsavai BPDU_BODY_T body;
57*4eaa4710SRishi Srivatsavai } CONFIG_BPDU_T;
58*4eaa4710SRishi Srivatsavai
59*4eaa4710SRishi Srivatsavai typedef struct tx_rstp_bpdu_t {
60*4eaa4710SRishi Srivatsavai MAC_HEADER_T mac;
61*4eaa4710SRishi Srivatsavai ETH_HEADER_T eth;
62*4eaa4710SRishi Srivatsavai BPDU_HEADER_T hdr;
63*4eaa4710SRishi Srivatsavai BPDU_BODY_T body;
64*4eaa4710SRishi Srivatsavai unsigned char ver_1_length[2];
65*4eaa4710SRishi Srivatsavai } RSTP_BPDU_T;
66*4eaa4710SRishi Srivatsavai
67*4eaa4710SRishi Srivatsavai
68*4eaa4710SRishi Srivatsavai static RSTP_BPDU_T bpdu_packet = {
69*4eaa4710SRishi Srivatsavai {/* MAC_HEADER_T */
70*4eaa4710SRishi Srivatsavai {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}, /* dst_mac */
71*4eaa4710SRishi Srivatsavai {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* src_mac */
72*4eaa4710SRishi Srivatsavai },
73*4eaa4710SRishi Srivatsavai { /* ETH_HEADER_T */
74*4eaa4710SRishi Srivatsavai {0x00, 0x00}, /* len8023 */
75*4eaa4710SRishi Srivatsavai BPDU_L_SAP, BPDU_L_SAP, LLC_UI /* dsap, ssap, llc */
76*4eaa4710SRishi Srivatsavai },
77*4eaa4710SRishi Srivatsavai {/* BPDU_HEADER_T */
78*4eaa4710SRishi Srivatsavai {0x00, 0x00}, /* protocol */
79*4eaa4710SRishi Srivatsavai BPDU_VERSION_ID, 0x00 /* version, bpdu_type */
80*4eaa4710SRishi Srivatsavai },
81*4eaa4710SRishi Srivatsavai {
82*4eaa4710SRishi Srivatsavai 0x00, /* flags; */
83*4eaa4710SRishi Srivatsavai {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* root_id[8]; */
84*4eaa4710SRishi Srivatsavai {0x00,0x00,0x00,0x00}, /* root_path_cost[4]; */
85*4eaa4710SRishi Srivatsavai {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* bridge_id[8]; */
86*4eaa4710SRishi Srivatsavai {0x00,0x00}, /* port_id[2]; */
87*4eaa4710SRishi Srivatsavai {0x00,0x00}, /* message_age[2]; */
88*4eaa4710SRishi Srivatsavai {0x00,0x00}, /* max_age[2]; */
89*4eaa4710SRishi Srivatsavai {0x00,0x00}, /* hello_time[2]; */
90*4eaa4710SRishi Srivatsavai {0x00,0x00}, /* forward_delay[2]; */
91*4eaa4710SRishi Srivatsavai },
92*4eaa4710SRishi Srivatsavai {0x00,0x00}, /* ver_1_length[2]; */
93*4eaa4710SRishi Srivatsavai };
94*4eaa4710SRishi Srivatsavai
95*4eaa4710SRishi Srivatsavai static size_t
build_bpdu_header(int port_index,unsigned char bpdu_type,unsigned short pkt_len)96*4eaa4710SRishi Srivatsavai build_bpdu_header (int port_index,
97*4eaa4710SRishi Srivatsavai unsigned char bpdu_type,
98*4eaa4710SRishi Srivatsavai unsigned short pkt_len)
99*4eaa4710SRishi Srivatsavai {
100*4eaa4710SRishi Srivatsavai unsigned short len8023;
101*4eaa4710SRishi Srivatsavai
102*4eaa4710SRishi Srivatsavai STP_OUT_get_port_mac (port_index, bpdu_packet.mac.src_mac);
103*4eaa4710SRishi Srivatsavai
104*4eaa4710SRishi Srivatsavai bpdu_packet.hdr.bpdu_type = bpdu_type;
105*4eaa4710SRishi Srivatsavai bpdu_packet.hdr.version = (BPDU_RSTP == bpdu_type) ?
106*4eaa4710SRishi Srivatsavai BPDU_VERSION_RAPID_ID :
107*4eaa4710SRishi Srivatsavai BPDU_VERSION_ID;
108*4eaa4710SRishi Srivatsavai
109*4eaa4710SRishi Srivatsavai /* NOTE: I suppose, that sizeof(unsigned short)=2 ! */
110*4eaa4710SRishi Srivatsavai len8023 = htons ((unsigned short) (pkt_len + 3));
111*4eaa4710SRishi Srivatsavai (void) memcpy (&bpdu_packet.eth.len8023, &len8023, 2);
112*4eaa4710SRishi Srivatsavai
113*4eaa4710SRishi Srivatsavai if (pkt_len < MIN_FRAME_LENGTH) pkt_len = MIN_FRAME_LENGTH;
114*4eaa4710SRishi Srivatsavai return pkt_len;
115*4eaa4710SRishi Srivatsavai }
116*4eaa4710SRishi Srivatsavai
117*4eaa4710SRishi Srivatsavai static int
txTcn(STATE_MACH_T * this)118*4eaa4710SRishi Srivatsavai txTcn (STATE_MACH_T* this)
119*4eaa4710SRishi Srivatsavai { /* 17.19.17 (page 68) & 9.3.2 (page 25) */
120*4eaa4710SRishi Srivatsavai register size_t pkt_len;
121*4eaa4710SRishi Srivatsavai register int port_index, vlan_id;
122*4eaa4710SRishi Srivatsavai
123*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
124*4eaa4710SRishi Srivatsavai if (this->owner.port->skip_tx > 0) {
125*4eaa4710SRishi Srivatsavai if (1 == this->owner.port->skip_tx)
126*4eaa4710SRishi Srivatsavai stp_trace ("port %s stop tx skipping",
127*4eaa4710SRishi Srivatsavai this->owner.port->port_name);
128*4eaa4710SRishi Srivatsavai this->owner.port->skip_tx--;
129*4eaa4710SRishi Srivatsavai return STP_Nothing_To_Do;
130*4eaa4710SRishi Srivatsavai }
131*4eaa4710SRishi Srivatsavai #endif
132*4eaa4710SRishi Srivatsavai
133*4eaa4710SRishi Srivatsavai if (this->owner.port->admin_non_stp) return 1;
134*4eaa4710SRishi Srivatsavai port_index = this->owner.port->port_index;
135*4eaa4710SRishi Srivatsavai vlan_id = this->owner.port->owner->vlan_id;
136*4eaa4710SRishi Srivatsavai
137*4eaa4710SRishi Srivatsavai pkt_len = build_bpdu_header (port_index,
138*4eaa4710SRishi Srivatsavai BPDU_TOPO_CHANGE_TYPE,
139*4eaa4710SRishi Srivatsavai sizeof (BPDU_HEADER_T));
140*4eaa4710SRishi Srivatsavai
141*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
142*4eaa4710SRishi Srivatsavai if (this->debug)
143*4eaa4710SRishi Srivatsavai stp_trace ("port %s txTcn", this->owner.port->port_name);
144*4eaa4710SRishi Srivatsavai #endif
145*4eaa4710SRishi Srivatsavai return STP_OUT_tx_bpdu (port_index, vlan_id,
146*4eaa4710SRishi Srivatsavai (unsigned char *) &bpdu_packet,
147*4eaa4710SRishi Srivatsavai pkt_len);
148*4eaa4710SRishi Srivatsavai }
149*4eaa4710SRishi Srivatsavai
150*4eaa4710SRishi Srivatsavai static void
build_config_bpdu(PORT_T * port,Bool set_topo_ack_flag)151*4eaa4710SRishi Srivatsavai build_config_bpdu (PORT_T* port, Bool set_topo_ack_flag)
152*4eaa4710SRishi Srivatsavai {
153*4eaa4710SRishi Srivatsavai bpdu_packet.body.flags = 0;
154*4eaa4710SRishi Srivatsavai if (port->tcWhile) {
155*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
156*4eaa4710SRishi Srivatsavai if (port->topoch->debug)
157*4eaa4710SRishi Srivatsavai stp_trace ("tcWhile=%d =>tx TOPOLOGY_CHANGE_BIT to port %s",
158*4eaa4710SRishi Srivatsavai (int) port->tcWhile, port->port_name);
159*4eaa4710SRishi Srivatsavai #endif
160*4eaa4710SRishi Srivatsavai bpdu_packet.body.flags |= TOPOLOGY_CHANGE_BIT;
161*4eaa4710SRishi Srivatsavai }
162*4eaa4710SRishi Srivatsavai
163*4eaa4710SRishi Srivatsavai if (set_topo_ack_flag && port->tcAck) {
164*4eaa4710SRishi Srivatsavai bpdu_packet.body.flags |= TOPOLOGY_CHANGE_ACK_BIT;
165*4eaa4710SRishi Srivatsavai }
166*4eaa4710SRishi Srivatsavai
167*4eaa4710SRishi Srivatsavai STP_VECT_set_vector (&port->portPrio, &bpdu_packet.body);
168*4eaa4710SRishi Srivatsavai STP_set_times (&port->portTimes, &bpdu_packet.body);
169*4eaa4710SRishi Srivatsavai }
170*4eaa4710SRishi Srivatsavai
171*4eaa4710SRishi Srivatsavai static int
txConfig(STATE_MACH_T * this)172*4eaa4710SRishi Srivatsavai txConfig (STATE_MACH_T* this)
173*4eaa4710SRishi Srivatsavai {/* 17.19.15 (page 67) & 9.3.1 (page 23) */
174*4eaa4710SRishi Srivatsavai register size_t pkt_len;
175*4eaa4710SRishi Srivatsavai register PORT_T* port = NULL;
176*4eaa4710SRishi Srivatsavai register int port_index, vlan_id;
177*4eaa4710SRishi Srivatsavai
178*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
179*4eaa4710SRishi Srivatsavai if (this->owner.port->skip_tx > 0) {
180*4eaa4710SRishi Srivatsavai if (1 == this->owner.port->skip_tx)
181*4eaa4710SRishi Srivatsavai stp_trace ("port %s stop tx skipping",
182*4eaa4710SRishi Srivatsavai this->owner.port->port_name);
183*4eaa4710SRishi Srivatsavai this->owner.port->skip_tx--;
184*4eaa4710SRishi Srivatsavai return STP_Nothing_To_Do;
185*4eaa4710SRishi Srivatsavai }
186*4eaa4710SRishi Srivatsavai #endif
187*4eaa4710SRishi Srivatsavai
188*4eaa4710SRishi Srivatsavai port = this->owner.port;
189*4eaa4710SRishi Srivatsavai if (port->admin_non_stp) return 1;
190*4eaa4710SRishi Srivatsavai port_index = port->port_index;
191*4eaa4710SRishi Srivatsavai vlan_id = port->owner->vlan_id;
192*4eaa4710SRishi Srivatsavai
193*4eaa4710SRishi Srivatsavai pkt_len = build_bpdu_header (port->port_index,
194*4eaa4710SRishi Srivatsavai BPDU_CONFIG_TYPE,
195*4eaa4710SRishi Srivatsavai sizeof (BPDU_HEADER_T) + sizeof (BPDU_BODY_T));
196*4eaa4710SRishi Srivatsavai build_config_bpdu (port, True);
197*4eaa4710SRishi Srivatsavai
198*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
199*4eaa4710SRishi Srivatsavai if (this->debug)
200*4eaa4710SRishi Srivatsavai stp_trace ("port %s txConfig flags=0X%lx",
201*4eaa4710SRishi Srivatsavai port->port_name,
202*4eaa4710SRishi Srivatsavai (unsigned long) bpdu_packet.body.flags);
203*4eaa4710SRishi Srivatsavai #endif
204*4eaa4710SRishi Srivatsavai return STP_OUT_tx_bpdu (port_index, vlan_id,
205*4eaa4710SRishi Srivatsavai (unsigned char *) &bpdu_packet,
206*4eaa4710SRishi Srivatsavai pkt_len);
207*4eaa4710SRishi Srivatsavai }
208*4eaa4710SRishi Srivatsavai
209*4eaa4710SRishi Srivatsavai static int
txRstp(STATE_MACH_T * this)210*4eaa4710SRishi Srivatsavai txRstp (STATE_MACH_T* this)
211*4eaa4710SRishi Srivatsavai {/* 17.19.16 (page 68) & 9.3.3 (page 25) */
212*4eaa4710SRishi Srivatsavai register size_t pkt_len;
213*4eaa4710SRishi Srivatsavai register PORT_T* port = NULL;
214*4eaa4710SRishi Srivatsavai register int port_index, vlan_id;
215*4eaa4710SRishi Srivatsavai unsigned char role;
216*4eaa4710SRishi Srivatsavai
217*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
218*4eaa4710SRishi Srivatsavai if (this->owner.port->skip_tx > 0) {
219*4eaa4710SRishi Srivatsavai if (1 == this->owner.port->skip_tx)
220*4eaa4710SRishi Srivatsavai stp_trace ("port %s stop tx skipping",
221*4eaa4710SRishi Srivatsavai this->owner.port->port_name);
222*4eaa4710SRishi Srivatsavai else
223*4eaa4710SRishi Srivatsavai stp_trace ("port %s skip tx %d",
224*4eaa4710SRishi Srivatsavai this->owner.port->port_name, this->owner.port->skip_tx);
225*4eaa4710SRishi Srivatsavai
226*4eaa4710SRishi Srivatsavai this->owner.port->skip_tx--;
227*4eaa4710SRishi Srivatsavai return STP_Nothing_To_Do;
228*4eaa4710SRishi Srivatsavai }
229*4eaa4710SRishi Srivatsavai #endif
230*4eaa4710SRishi Srivatsavai
231*4eaa4710SRishi Srivatsavai port = this->owner.port;
232*4eaa4710SRishi Srivatsavai if (port->admin_non_stp) return 1;
233*4eaa4710SRishi Srivatsavai port_index = port->port_index;
234*4eaa4710SRishi Srivatsavai vlan_id = port->owner->vlan_id;
235*4eaa4710SRishi Srivatsavai
236*4eaa4710SRishi Srivatsavai pkt_len = build_bpdu_header (port->port_index,
237*4eaa4710SRishi Srivatsavai BPDU_RSTP,
238*4eaa4710SRishi Srivatsavai sizeof (BPDU_HEADER_T) + sizeof (BPDU_BODY_T) + 2);
239*4eaa4710SRishi Srivatsavai build_config_bpdu (port, False);
240*4eaa4710SRishi Srivatsavai
241*4eaa4710SRishi Srivatsavai switch (port->selectedRole) {
242*4eaa4710SRishi Srivatsavai default:
243*4eaa4710SRishi Srivatsavai case DisabledPort:
244*4eaa4710SRishi Srivatsavai role = RSTP_PORT_ROLE_UNKN;
245*4eaa4710SRishi Srivatsavai break;
246*4eaa4710SRishi Srivatsavai case AlternatePort:
247*4eaa4710SRishi Srivatsavai role = RSTP_PORT_ROLE_ALTBACK;
248*4eaa4710SRishi Srivatsavai break;
249*4eaa4710SRishi Srivatsavai case BackupPort:
250*4eaa4710SRishi Srivatsavai role = RSTP_PORT_ROLE_ALTBACK;
251*4eaa4710SRishi Srivatsavai break;
252*4eaa4710SRishi Srivatsavai case RootPort:
253*4eaa4710SRishi Srivatsavai role = RSTP_PORT_ROLE_ROOT;
254*4eaa4710SRishi Srivatsavai break;
255*4eaa4710SRishi Srivatsavai case DesignatedPort:
256*4eaa4710SRishi Srivatsavai role = RSTP_PORT_ROLE_DESGN;
257*4eaa4710SRishi Srivatsavai break;
258*4eaa4710SRishi Srivatsavai }
259*4eaa4710SRishi Srivatsavai
260*4eaa4710SRishi Srivatsavai bpdu_packet.body.flags |= (role << PORT_ROLE_OFFS);
261*4eaa4710SRishi Srivatsavai
262*4eaa4710SRishi Srivatsavai if (port->synced) {
263*4eaa4710SRishi Srivatsavai #if 0 /* def STP_DBG */
264*4eaa4710SRishi Srivatsavai if (port->roletrns->debug)
265*4eaa4710SRishi Srivatsavai stp_trace ("tx AGREEMENT_BIT to port %s", port->port_name);
266*4eaa4710SRishi Srivatsavai #endif
267*4eaa4710SRishi Srivatsavai bpdu_packet.body.flags |= AGREEMENT_BIT;
268*4eaa4710SRishi Srivatsavai }
269*4eaa4710SRishi Srivatsavai
270*4eaa4710SRishi Srivatsavai if (port->proposing) {
271*4eaa4710SRishi Srivatsavai #if 0 /* def STP_DBG */
272*4eaa4710SRishi Srivatsavai if (port->roletrns->debug)
273*4eaa4710SRishi Srivatsavai stp_trace ("tx PROPOSAL_BIT to port %s", port->port_name);
274*4eaa4710SRishi Srivatsavai #endif
275*4eaa4710SRishi Srivatsavai bpdu_packet.body.flags |= PROPOSAL_BIT;
276*4eaa4710SRishi Srivatsavai }
277*4eaa4710SRishi Srivatsavai
278*4eaa4710SRishi Srivatsavai #ifdef STP_DBG
279*4eaa4710SRishi Srivatsavai if (this->debug)
280*4eaa4710SRishi Srivatsavai stp_trace ("port %s txRstp flags=0X%lx",
281*4eaa4710SRishi Srivatsavai port->port_name,
282*4eaa4710SRishi Srivatsavai (unsigned long) bpdu_packet.body.flags);
283*4eaa4710SRishi Srivatsavai #endif
284*4eaa4710SRishi Srivatsavai
285*4eaa4710SRishi Srivatsavai return STP_OUT_tx_bpdu (port_index, vlan_id,
286*4eaa4710SRishi Srivatsavai (unsigned char *) &bpdu_packet,
287*4eaa4710SRishi Srivatsavai pkt_len);
288*4eaa4710SRishi Srivatsavai }
289*4eaa4710SRishi Srivatsavai
290*4eaa4710SRishi Srivatsavai void
STP_transmit_enter_state(STATE_MACH_T * this)291*4eaa4710SRishi Srivatsavai STP_transmit_enter_state (STATE_MACH_T* this)
292*4eaa4710SRishi Srivatsavai {
293*4eaa4710SRishi Srivatsavai register PORT_T* port = this->owner.port;
294*4eaa4710SRishi Srivatsavai
295*4eaa4710SRishi Srivatsavai switch (this->State) {
296*4eaa4710SRishi Srivatsavai case BEGIN:
297*4eaa4710SRishi Srivatsavai case TRANSMIT_INIT:
298*4eaa4710SRishi Srivatsavai port->newInfo = False;
299*4eaa4710SRishi Srivatsavai port->helloWhen = 0;
300*4eaa4710SRishi Srivatsavai port->txCount = 0;
301*4eaa4710SRishi Srivatsavai break;
302*4eaa4710SRishi Srivatsavai case TRANSMIT_PERIODIC:
303*4eaa4710SRishi Srivatsavai port->newInfo = port->newInfo ||
304*4eaa4710SRishi Srivatsavai ((port->role == DesignatedPort) ||
305*4eaa4710SRishi Srivatsavai ((port->role == RootPort) && port->tcWhile));
306*4eaa4710SRishi Srivatsavai port->helloWhen = port->owner->rootTimes.HelloTime;
307*4eaa4710SRishi Srivatsavai break;
308*4eaa4710SRishi Srivatsavai case IDLE:
309*4eaa4710SRishi Srivatsavai break;
310*4eaa4710SRishi Srivatsavai case TRANSMIT_CONFIG:
311*4eaa4710SRishi Srivatsavai port->newInfo = False;
312*4eaa4710SRishi Srivatsavai (void) txConfig (this);
313*4eaa4710SRishi Srivatsavai port->txCount++;
314*4eaa4710SRishi Srivatsavai port->tcAck = False;
315*4eaa4710SRishi Srivatsavai break;
316*4eaa4710SRishi Srivatsavai case TRANSMIT_TCN:
317*4eaa4710SRishi Srivatsavai port->newInfo = False;
318*4eaa4710SRishi Srivatsavai (void) txTcn (this);
319*4eaa4710SRishi Srivatsavai port->txCount++;
320*4eaa4710SRishi Srivatsavai break;
321*4eaa4710SRishi Srivatsavai case TRANSMIT_RSTP:
322*4eaa4710SRishi Srivatsavai port->newInfo = False;
323*4eaa4710SRishi Srivatsavai (void) txRstp (this);
324*4eaa4710SRishi Srivatsavai port->txCount++;
325*4eaa4710SRishi Srivatsavai port->tcAck = False;
326*4eaa4710SRishi Srivatsavai break;
327*4eaa4710SRishi Srivatsavai };
328*4eaa4710SRishi Srivatsavai }
329*4eaa4710SRishi Srivatsavai
330*4eaa4710SRishi Srivatsavai Bool
STP_transmit_check_conditions(STATE_MACH_T * this)331*4eaa4710SRishi Srivatsavai STP_transmit_check_conditions (STATE_MACH_T* this)
332*4eaa4710SRishi Srivatsavai {
333*4eaa4710SRishi Srivatsavai register PORT_T* port = this->owner.port;
334*4eaa4710SRishi Srivatsavai
335*4eaa4710SRishi Srivatsavai switch (this->State) {
336*4eaa4710SRishi Srivatsavai case BEGIN:
337*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, TRANSMIT_INIT);
338*4eaa4710SRishi Srivatsavai case TRANSMIT_INIT:
339*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, IDLE);
340*4eaa4710SRishi Srivatsavai case TRANSMIT_PERIODIC:
341*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, IDLE);
342*4eaa4710SRishi Srivatsavai case IDLE:
343*4eaa4710SRishi Srivatsavai if (!port->helloWhen) return STP_hop_2_state (this, TRANSMIT_PERIODIC);
344*4eaa4710SRishi Srivatsavai if (!port->sendRSTP && port->newInfo &&
345*4eaa4710SRishi Srivatsavai (port->txCount < TxHoldCount) &&
346*4eaa4710SRishi Srivatsavai (port->role == DesignatedPort) &&
347*4eaa4710SRishi Srivatsavai port->helloWhen)
348*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, TRANSMIT_CONFIG);
349*4eaa4710SRishi Srivatsavai if (!port->sendRSTP && port->newInfo &&
350*4eaa4710SRishi Srivatsavai (port->txCount < TxHoldCount) &&
351*4eaa4710SRishi Srivatsavai (port->role == RootPort) &&
352*4eaa4710SRishi Srivatsavai port->helloWhen)
353*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, TRANSMIT_TCN);
354*4eaa4710SRishi Srivatsavai if (port->sendRSTP && port->newInfo &&
355*4eaa4710SRishi Srivatsavai (port->txCount < TxHoldCount) &&
356*4eaa4710SRishi Srivatsavai ((port->role == RootPort) ||
357*4eaa4710SRishi Srivatsavai (port->role == DesignatedPort)))
358*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, TRANSMIT_RSTP);
359*4eaa4710SRishi Srivatsavai break;
360*4eaa4710SRishi Srivatsavai case TRANSMIT_CONFIG:
361*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, IDLE);
362*4eaa4710SRishi Srivatsavai case TRANSMIT_TCN:
363*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, IDLE);
364*4eaa4710SRishi Srivatsavai case TRANSMIT_RSTP:
365*4eaa4710SRishi Srivatsavai return STP_hop_2_state (this, IDLE);
366*4eaa4710SRishi Srivatsavai };
367*4eaa4710SRishi Srivatsavai return False;
368*4eaa4710SRishi Srivatsavai }
369