xref: /onnv-gate/usr/src/lib/librstp/common/portinfo.c (revision 10491:8893b747ecdf)
1*10491SRishi.Srivatsavai@Sun.COM /************************************************************************
2*10491SRishi.Srivatsavai@Sun.COM  * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
3*10491SRishi.Srivatsavai@Sun.COM  * Copyright (C) 2001-2003 Optical Access
4*10491SRishi.Srivatsavai@Sun.COM  * Author: Alex Rozin
5*10491SRishi.Srivatsavai@Sun.COM  *
6*10491SRishi.Srivatsavai@Sun.COM  * This file is part of RSTP library.
7*10491SRishi.Srivatsavai@Sun.COM  *
8*10491SRishi.Srivatsavai@Sun.COM  * RSTP library is free software; you can redistribute it and/or modify it
9*10491SRishi.Srivatsavai@Sun.COM  * under the terms of the GNU Lesser General Public License as published by the
10*10491SRishi.Srivatsavai@Sun.COM  * Free Software Foundation; version 2.1
11*10491SRishi.Srivatsavai@Sun.COM  *
12*10491SRishi.Srivatsavai@Sun.COM  * RSTP library is distributed in the hope that it will be useful, but
13*10491SRishi.Srivatsavai@Sun.COM  * WITHOUT ANY WARRANTY; without even the implied warranty of
14*10491SRishi.Srivatsavai@Sun.COM  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15*10491SRishi.Srivatsavai@Sun.COM  * General Public License for more details.
16*10491SRishi.Srivatsavai@Sun.COM  *
17*10491SRishi.Srivatsavai@Sun.COM  * You should have received a copy of the GNU Lesser General Public License
18*10491SRishi.Srivatsavai@Sun.COM  * along with RSTP library; see the file COPYING.  If not, write to the Free
19*10491SRishi.Srivatsavai@Sun.COM  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20*10491SRishi.Srivatsavai@Sun.COM  * 02111-1307, USA.
21*10491SRishi.Srivatsavai@Sun.COM  **********************************************************************/
22*10491SRishi.Srivatsavai@Sun.COM 
23*10491SRishi.Srivatsavai@Sun.COM #include "base.h"
24*10491SRishi.Srivatsavai@Sun.COM #include "stpm.h"
25*10491SRishi.Srivatsavai@Sun.COM #include "stp_vectors.h"
26*10491SRishi.Srivatsavai@Sun.COM 
27*10491SRishi.Srivatsavai@Sun.COM /* The Port Information State Machine : 17.21 */
28*10491SRishi.Srivatsavai@Sun.COM 
29*10491SRishi.Srivatsavai@Sun.COM #define STATES { \
30*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(DISABLED), \
31*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(ENABLED),  \
32*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(AGED),     \
33*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(UPDATE),   \
34*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(CURRENT),  \
35*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(RECEIVE),  \
36*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(SUPERIOR), \
37*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(REPEAT),   \
38*10491SRishi.Srivatsavai@Sun.COM   CHOOSE(AGREEMENT)    \
39*10491SRishi.Srivatsavai@Sun.COM }
40*10491SRishi.Srivatsavai@Sun.COM 
41*10491SRishi.Srivatsavai@Sun.COM #define GET_STATE_NAME STP_info_get_state_name
42*10491SRishi.Srivatsavai@Sun.COM #include "choose.h"
43*10491SRishi.Srivatsavai@Sun.COM 
44*10491SRishi.Srivatsavai@Sun.COM #if 0 /* for debug */
45*10491SRishi.Srivatsavai@Sun.COM void
46*10491SRishi.Srivatsavai@Sun.COM _stp_dump (char* title, unsigned char* buff, int len)
47*10491SRishi.Srivatsavai@Sun.COM {
48*10491SRishi.Srivatsavai@Sun.COM   register int iii;
49*10491SRishi.Srivatsavai@Sun.COM 
50*10491SRishi.Srivatsavai@Sun.COM   stp_trace ("\n%s:", title);
51*10491SRishi.Srivatsavai@Sun.COM   for (iii = 0; iii < len; iii++) {
52*10491SRishi.Srivatsavai@Sun.COM     if (! (iii % 24)) stp_trace ("\n%6d:", iii);
53*10491SRishi.Srivatsavai@Sun.COM     if (! (iii % 8)) stp_trace (" ");
54*10491SRishi.Srivatsavai@Sun.COM     stp_trace ("%02lx", (unsigned long) buff[iii]);
55*10491SRishi.Srivatsavai@Sun.COM   }
56*10491SRishi.Srivatsavai@Sun.COM   stp_trace ("\n");
57*10491SRishi.Srivatsavai@Sun.COM }
58*10491SRishi.Srivatsavai@Sun.COM #endif
59*10491SRishi.Srivatsavai@Sun.COM 
60*10491SRishi.Srivatsavai@Sun.COM static RCVD_MSG_T
rcvBpdu(STATE_MACH_T * this)61*10491SRishi.Srivatsavai@Sun.COM rcvBpdu (STATE_MACH_T* this)
62*10491SRishi.Srivatsavai@Sun.COM {/* 17.19.8 */
63*10491SRishi.Srivatsavai@Sun.COM   int   bridcmp;
64*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port = this->owner.port;
65*10491SRishi.Srivatsavai@Sun.COM 
66*10491SRishi.Srivatsavai@Sun.COM   if (port->msgBpduType == BPDU_TOPO_CHANGE_TYPE) {
67*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
68*10491SRishi.Srivatsavai@Sun.COM     if (this->debug) {
69*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("%s", "rcvBpdu: OtherMsg:BPDU_TOPO_CHANGE_TYPE");
70*10491SRishi.Srivatsavai@Sun.COM     }
71*10491SRishi.Srivatsavai@Sun.COM #endif
72*10491SRishi.Srivatsavai@Sun.COM     return OtherMsg;
73*10491SRishi.Srivatsavai@Sun.COM   }
74*10491SRishi.Srivatsavai@Sun.COM 
75*10491SRishi.Srivatsavai@Sun.COM   port->msgPortRole = RSTP_PORT_ROLE_UNKN;
76*10491SRishi.Srivatsavai@Sun.COM 
77*10491SRishi.Srivatsavai@Sun.COM   if (BPDU_RSTP == port->msgBpduType) {
78*10491SRishi.Srivatsavai@Sun.COM     port->msgPortRole = (port->msgFlags & PORT_ROLE_MASK) >> PORT_ROLE_OFFS;
79*10491SRishi.Srivatsavai@Sun.COM   }
80*10491SRishi.Srivatsavai@Sun.COM 
81*10491SRishi.Srivatsavai@Sun.COM   if (RSTP_PORT_ROLE_DESGN == port->msgPortRole ||
82*10491SRishi.Srivatsavai@Sun.COM       BPDU_CONFIG_TYPE == port->msgBpduType) {
83*10491SRishi.Srivatsavai@Sun.COM     bridcmp = STP_VECT_compare_vector (&port->msgPrio, &port->portPrio);
84*10491SRishi.Srivatsavai@Sun.COM 
85*10491SRishi.Srivatsavai@Sun.COM     if (bridcmp < 0 ||
86*10491SRishi.Srivatsavai@Sun.COM         (! STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
87*10491SRishi.Srivatsavai@Sun.COM                                        &port->portPrio.design_bridge) &&
88*10491SRishi.Srivatsavai@Sun.COM          port->msgPrio.design_port == port->portPrio.design_port      &&
89*10491SRishi.Srivatsavai@Sun.COM          STP_compare_times (&port->msgTimes, &port->portTimes))) {
90*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
91*10491SRishi.Srivatsavai@Sun.COM          if (this->debug) {
92*10491SRishi.Srivatsavai@Sun.COM            stp_trace ("rcvBpdu: SuperiorDesignateMsg:bridcmp=%d", (int) bridcmp);
93*10491SRishi.Srivatsavai@Sun.COM          }
94*10491SRishi.Srivatsavai@Sun.COM #endif
95*10491SRishi.Srivatsavai@Sun.COM       return SuperiorDesignateMsg;
96*10491SRishi.Srivatsavai@Sun.COM     }
97*10491SRishi.Srivatsavai@Sun.COM   }
98*10491SRishi.Srivatsavai@Sun.COM 
99*10491SRishi.Srivatsavai@Sun.COM   if (BPDU_CONFIG_TYPE == port->msgBpduType ||
100*10491SRishi.Srivatsavai@Sun.COM       RSTP_PORT_ROLE_DESGN == port->msgPortRole) {
101*10491SRishi.Srivatsavai@Sun.COM     if (! STP_VECT_compare_vector (&port->msgPrio,
102*10491SRishi.Srivatsavai@Sun.COM                                    &port->portPrio) &&
103*10491SRishi.Srivatsavai@Sun.COM         ! STP_compare_times (&port->msgTimes, &port->portTimes)) {
104*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
105*10491SRishi.Srivatsavai@Sun.COM         if (this->debug) {
106*10491SRishi.Srivatsavai@Sun.COM           stp_trace ("%s", "rcvBpdu: RepeatedDesignateMsg");
107*10491SRishi.Srivatsavai@Sun.COM         }
108*10491SRishi.Srivatsavai@Sun.COM #endif
109*10491SRishi.Srivatsavai@Sun.COM         return RepeatedDesignateMsg;
110*10491SRishi.Srivatsavai@Sun.COM     }
111*10491SRishi.Srivatsavai@Sun.COM   }
112*10491SRishi.Srivatsavai@Sun.COM 
113*10491SRishi.Srivatsavai@Sun.COM   if (RSTP_PORT_ROLE_ROOT == port->msgBpduType                    &&
114*10491SRishi.Srivatsavai@Sun.COM       port->operPointToPointMac                                   &&
115*10491SRishi.Srivatsavai@Sun.COM       ! STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
116*10491SRishi.Srivatsavai@Sun.COM                                     &port->portPrio.design_bridge) &&
117*10491SRishi.Srivatsavai@Sun.COM       AGREEMENT_BIT & port->msgFlags) {
118*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
119*10491SRishi.Srivatsavai@Sun.COM     if (this->debug) {
120*10491SRishi.Srivatsavai@Sun.COM       stp_trace ("%s", "rcvBpdu: ConfirmedRootMsg");
121*10491SRishi.Srivatsavai@Sun.COM     }
122*10491SRishi.Srivatsavai@Sun.COM #endif
123*10491SRishi.Srivatsavai@Sun.COM     return ConfirmedRootMsg;
124*10491SRishi.Srivatsavai@Sun.COM   }
125*10491SRishi.Srivatsavai@Sun.COM 
126*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
127*10491SRishi.Srivatsavai@Sun.COM     if (this->debug) {
128*10491SRishi.Srivatsavai@Sun.COM       if (RSTP_PORT_ROLE_ROOT == port->msgBpduType) {
129*10491SRishi.Srivatsavai@Sun.COM 	if (!port->operPointToPointMac) {
130*10491SRishi.Srivatsavai@Sun.COM 	  stp_trace("rcvBpdu: OtherMsg: not point-to-point MAC");
131*10491SRishi.Srivatsavai@Sun.COM 	} else if (STP_VECT_compare_bridge_id (&port->msgPrio.design_bridge,
132*10491SRishi.Srivatsavai@Sun.COM 	  &port->portPrio.design_bridge)) {
133*10491SRishi.Srivatsavai@Sun.COM 	  STP_VECT_br_id_print("rcvBpdu: OtherMsg: msgPrio", &port->msgPrio.design_bridge, True);
134*10491SRishi.Srivatsavai@Sun.COM 	  STP_VECT_br_id_print("rcvBpdu:          portPrio", &port->portPrio.design_bridge, True);
135*10491SRishi.Srivatsavai@Sun.COM 	} else {
136*10491SRishi.Srivatsavai@Sun.COM 	  stp_trace("rcvBpdu: OtherMsg: agreement bit not set");
137*10491SRishi.Srivatsavai@Sun.COM 	}
138*10491SRishi.Srivatsavai@Sun.COM       } else {
139*10491SRishi.Srivatsavai@Sun.COM 	stp_trace ("rcvBpdu: OtherMsg: type %d", port->msgBpduType);
140*10491SRishi.Srivatsavai@Sun.COM       }
141*10491SRishi.Srivatsavai@Sun.COM     }
142*10491SRishi.Srivatsavai@Sun.COM #endif
143*10491SRishi.Srivatsavai@Sun.COM   return OtherMsg;
144*10491SRishi.Srivatsavai@Sun.COM }
145*10491SRishi.Srivatsavai@Sun.COM 
146*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */
147*10491SRishi.Srivatsavai@Sun.COM static Bool
recordProposed(STATE_MACH_T * this,char * reason)148*10491SRishi.Srivatsavai@Sun.COM recordProposed (STATE_MACH_T* this, char* reason)
149*10491SRishi.Srivatsavai@Sun.COM {/* 17.19.9 */
150*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port = this->owner.port;
151*10491SRishi.Srivatsavai@Sun.COM 
152*10491SRishi.Srivatsavai@Sun.COM   if (RSTP_PORT_ROLE_DESGN == port->msgPortRole &&
153*10491SRishi.Srivatsavai@Sun.COM       (PROPOSAL_BIT & port->msgFlags)           &&
154*10491SRishi.Srivatsavai@Sun.COM       port->operPointToPointMac) {
155*10491SRishi.Srivatsavai@Sun.COM     return True;
156*10491SRishi.Srivatsavai@Sun.COM   }
157*10491SRishi.Srivatsavai@Sun.COM   return False;
158*10491SRishi.Srivatsavai@Sun.COM }
159*10491SRishi.Srivatsavai@Sun.COM 
160*10491SRishi.Srivatsavai@Sun.COM static void
setTcFlags(STATE_MACH_T * this)161*10491SRishi.Srivatsavai@Sun.COM setTcFlags (STATE_MACH_T* this)
162*10491SRishi.Srivatsavai@Sun.COM {/* 17.19.13 */
163*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port = this->owner.port;
164*10491SRishi.Srivatsavai@Sun.COM 
165*10491SRishi.Srivatsavai@Sun.COM   if (BPDU_TOPO_CHANGE_TYPE == port->msgBpduType) {
166*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
167*10491SRishi.Srivatsavai@Sun.COM       if (this->debug) {
168*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("port %s rx rcvdTcn", port->port_name);
169*10491SRishi.Srivatsavai@Sun.COM       }
170*10491SRishi.Srivatsavai@Sun.COM #endif
171*10491SRishi.Srivatsavai@Sun.COM     port->rcvdTcn = True;
172*10491SRishi.Srivatsavai@Sun.COM   } else {
173*10491SRishi.Srivatsavai@Sun.COM     if (TOPOLOGY_CHANGE_BIT & port->msgFlags) {
174*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
175*10491SRishi.Srivatsavai@Sun.COM       if (this->debug) {
176*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("(%s-%s) rx rcvdTc 0X%lx",
177*10491SRishi.Srivatsavai@Sun.COM             port->owner->name, port->port_name,
178*10491SRishi.Srivatsavai@Sun.COM             (unsigned long) port->msgFlags);
179*10491SRishi.Srivatsavai@Sun.COM       }
180*10491SRishi.Srivatsavai@Sun.COM #endif
181*10491SRishi.Srivatsavai@Sun.COM       port->rcvdTc = True;
182*10491SRishi.Srivatsavai@Sun.COM     }
183*10491SRishi.Srivatsavai@Sun.COM     if (TOPOLOGY_CHANGE_ACK_BIT & port->msgFlags) {
184*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
185*10491SRishi.Srivatsavai@Sun.COM       if (this->debug) {
186*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("port %s rx rcvdTcAck 0X%lx",
187*10491SRishi.Srivatsavai@Sun.COM             port->port_name,
188*10491SRishi.Srivatsavai@Sun.COM             (unsigned long) port->msgFlags);
189*10491SRishi.Srivatsavai@Sun.COM       }
190*10491SRishi.Srivatsavai@Sun.COM #endif
191*10491SRishi.Srivatsavai@Sun.COM       port->rcvdTcAck = True;
192*10491SRishi.Srivatsavai@Sun.COM     }
193*10491SRishi.Srivatsavai@Sun.COM   }
194*10491SRishi.Srivatsavai@Sun.COM }
195*10491SRishi.Srivatsavai@Sun.COM 
196*10491SRishi.Srivatsavai@Sun.COM static void
updtBPDUVersion(STATE_MACH_T * this)197*10491SRishi.Srivatsavai@Sun.COM updtBPDUVersion (STATE_MACH_T* this)
198*10491SRishi.Srivatsavai@Sun.COM {/* 17.19.18 */
199*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port = this->owner.port;
200*10491SRishi.Srivatsavai@Sun.COM 
201*10491SRishi.Srivatsavai@Sun.COM   if (BPDU_TOPO_CHANGE_TYPE == port->msgBpduType) {
202*10491SRishi.Srivatsavai@Sun.COM     port->rcvdSTP = True;
203*10491SRishi.Srivatsavai@Sun.COM   }
204*10491SRishi.Srivatsavai@Sun.COM 
205*10491SRishi.Srivatsavai@Sun.COM   if (port->msgBpduVersion < 2) {
206*10491SRishi.Srivatsavai@Sun.COM     port->rcvdSTP = True;
207*10491SRishi.Srivatsavai@Sun.COM   }
208*10491SRishi.Srivatsavai@Sun.COM 
209*10491SRishi.Srivatsavai@Sun.COM   if (BPDU_RSTP == port->msgBpduType) {
210*10491SRishi.Srivatsavai@Sun.COM     /* port->port->owner->ForceVersion >= NORMAL_RSTP
211*10491SRishi.Srivatsavai@Sun.COM        we have checked in STP_info_rx_bpdu */
212*10491SRishi.Srivatsavai@Sun.COM     port->rcvdRSTP = True;
213*10491SRishi.Srivatsavai@Sun.COM   }
214*10491SRishi.Srivatsavai@Sun.COM }
215*10491SRishi.Srivatsavai@Sun.COM 
216*10491SRishi.Srivatsavai@Sun.COM static void
updtRcvdInfoWhile(STATE_MACH_T * this)217*10491SRishi.Srivatsavai@Sun.COM updtRcvdInfoWhile (STATE_MACH_T* this)
218*10491SRishi.Srivatsavai@Sun.COM {/* 17.19.19 */
219*10491SRishi.Srivatsavai@Sun.COM   register int eff_age, dm, dt;
220*10491SRishi.Srivatsavai@Sun.COM   register int hello3;
221*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port = this->owner.port;
222*10491SRishi.Srivatsavai@Sun.COM 
223*10491SRishi.Srivatsavai@Sun.COM   eff_age = ( + port->portTimes.MaxAge) / 16;
224*10491SRishi.Srivatsavai@Sun.COM   if (eff_age < 1) eff_age = 1;
225*10491SRishi.Srivatsavai@Sun.COM   eff_age += port->portTimes.MessageAge;
226*10491SRishi.Srivatsavai@Sun.COM 
227*10491SRishi.Srivatsavai@Sun.COM   if (eff_age <= port->portTimes.MaxAge) {
228*10491SRishi.Srivatsavai@Sun.COM     hello3 = 3 *  port->portTimes.HelloTime;
229*10491SRishi.Srivatsavai@Sun.COM     dm = port->portTimes.MaxAge - eff_age;
230*10491SRishi.Srivatsavai@Sun.COM     if (dm > hello3)
231*10491SRishi.Srivatsavai@Sun.COM       dt = hello3;
232*10491SRishi.Srivatsavai@Sun.COM     else
233*10491SRishi.Srivatsavai@Sun.COM       dt = dm;
234*10491SRishi.Srivatsavai@Sun.COM     port->rcvdInfoWhile = dt;
235*10491SRishi.Srivatsavai@Sun.COM /****
236*10491SRishi.Srivatsavai@Sun.COM     stp_trace ("ma=%d eff_age=%d dm=%d dt=%d p=%s",
237*10491SRishi.Srivatsavai@Sun.COM                (int) port->portTimes.MessageAge,
238*10491SRishi.Srivatsavai@Sun.COM                (int) eff_age, (int) dm, (int) dt, port->port_name);
239*10491SRishi.Srivatsavai@Sun.COM ****/
240*10491SRishi.Srivatsavai@Sun.COM   } else {
241*10491SRishi.Srivatsavai@Sun.COM     port->rcvdInfoWhile = 0;
242*10491SRishi.Srivatsavai@Sun.COM /****/
243*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
244*10491SRishi.Srivatsavai@Sun.COM     /*if (this->debug) */
245*10491SRishi.Srivatsavai@Sun.COM     {
246*10491SRishi.Srivatsavai@Sun.COM       stp_trace ("port %s: MaxAge=%d MessageAge=%d HelloTime=%d rcvdInfoWhile=null !",
247*10491SRishi.Srivatsavai@Sun.COM             port->port_name,
248*10491SRishi.Srivatsavai@Sun.COM                 (int) port->portTimes.MaxAge,
249*10491SRishi.Srivatsavai@Sun.COM                 (int) port->portTimes.MessageAge,
250*10491SRishi.Srivatsavai@Sun.COM                 (int) port->portTimes.HelloTime);
251*10491SRishi.Srivatsavai@Sun.COM     }
252*10491SRishi.Srivatsavai@Sun.COM #endif
253*10491SRishi.Srivatsavai@Sun.COM /****/
254*10491SRishi.Srivatsavai@Sun.COM   }
255*10491SRishi.Srivatsavai@Sun.COM }
256*10491SRishi.Srivatsavai@Sun.COM 
257*10491SRishi.Srivatsavai@Sun.COM 
258*10491SRishi.Srivatsavai@Sun.COM /* ARGSUSED */
259*10491SRishi.Srivatsavai@Sun.COM void
STP_info_rx_bpdu(PORT_T * port,struct stp_bpdu_t * bpdu,size_t len)260*10491SRishi.Srivatsavai@Sun.COM STP_info_rx_bpdu (PORT_T* port, struct stp_bpdu_t* bpdu, size_t len)
261*10491SRishi.Srivatsavai@Sun.COM {
262*10491SRishi.Srivatsavai@Sun.COM #if 0
263*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("\nall BPDU", ((unsigned char*) bpdu) - 12, len + 12);
264*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("ETH_HEADER", (unsigned char*) &bpdu->eth, 5);
265*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("BPDU_HEADER", (unsigned char*) &bpdu->hdr, 4);
266*10491SRishi.Srivatsavai@Sun.COM   stp_trace ("protocol=%02x%02x version=%02x bpdu_type=%02x\n",
267*10491SRishi.Srivatsavai@Sun.COM      bpdu->hdr.protocol[0], bpdu->hdr.protocol[1],
268*10491SRishi.Srivatsavai@Sun.COM      bpdu->hdr.version, bpdu->hdr.bpdu_type);
269*10491SRishi.Srivatsavai@Sun.COM 
270*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("\nBPDU_BODY", (unsigned char*) &bpdu->body, sizeof (BPDU_BODY_T) + 2);
271*10491SRishi.Srivatsavai@Sun.COM   stp_trace ("flags=%02x\n", bpdu->body.flags);
272*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("root_id", bpdu->body.root_id, 8);
273*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("root_path_cost", bpdu->body.root_path_cost, 4);
274*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("bridge_id", bpdu->body.bridge_id, 8);
275*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("port_id", bpdu->body.port_id, 2);
276*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("message_age", bpdu->body.message_age, 2);
277*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("max_age", bpdu->body.max_age, 2);
278*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("hello_time", bpdu->body.hello_time, 2);
279*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("forward_delay", bpdu->body.forward_delay, 2);
280*10491SRishi.Srivatsavai@Sun.COM   _stp_dump ("ver_1_len", bpdu->ver_1_len, 2);
281*10491SRishi.Srivatsavai@Sun.COM #endif
282*10491SRishi.Srivatsavai@Sun.COM 
283*10491SRishi.Srivatsavai@Sun.COM   /* check bpdu type */
284*10491SRishi.Srivatsavai@Sun.COM   switch (bpdu->hdr.bpdu_type) {
285*10491SRishi.Srivatsavai@Sun.COM     case BPDU_CONFIG_TYPE:
286*10491SRishi.Srivatsavai@Sun.COM       port->rx_cfg_bpdu_cnt++;
287*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
288*10491SRishi.Srivatsavai@Sun.COM       if (port->info->debug)
289*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("CfgBpdu on port %s", port->port_name);
290*10491SRishi.Srivatsavai@Sun.COM #endif
291*10491SRishi.Srivatsavai@Sun.COM       if (port->admin_non_stp) return;
292*10491SRishi.Srivatsavai@Sun.COM       port->rcvdBpdu = True;
293*10491SRishi.Srivatsavai@Sun.COM       break;
294*10491SRishi.Srivatsavai@Sun.COM     case BPDU_TOPO_CHANGE_TYPE:
295*10491SRishi.Srivatsavai@Sun.COM       port->rx_tcn_bpdu_cnt++;
296*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
297*10491SRishi.Srivatsavai@Sun.COM       if (port->info->debug)
298*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("TcnBpdu on port %s", port->port_name);
299*10491SRishi.Srivatsavai@Sun.COM #endif
300*10491SRishi.Srivatsavai@Sun.COM       if (port->admin_non_stp) return;
301*10491SRishi.Srivatsavai@Sun.COM       port->rcvdBpdu = True;
302*10491SRishi.Srivatsavai@Sun.COM       port->msgBpduVersion = bpdu->hdr.version;
303*10491SRishi.Srivatsavai@Sun.COM       port->msgBpduType = bpdu->hdr.bpdu_type;
304*10491SRishi.Srivatsavai@Sun.COM       return;
305*10491SRishi.Srivatsavai@Sun.COM     default:
306*10491SRishi.Srivatsavai@Sun.COM       stp_trace ("RX undef bpdu type=%d", (int) bpdu->hdr.bpdu_type);
307*10491SRishi.Srivatsavai@Sun.COM       return;
308*10491SRishi.Srivatsavai@Sun.COM     case BPDU_RSTP:
309*10491SRishi.Srivatsavai@Sun.COM       port->rx_rstp_bpdu_cnt++;
310*10491SRishi.Srivatsavai@Sun.COM       if (port->admin_non_stp) return;
311*10491SRishi.Srivatsavai@Sun.COM       if (port->owner->ForceVersion >= NORMAL_RSTP) {
312*10491SRishi.Srivatsavai@Sun.COM         port->rcvdBpdu = True;
313*10491SRishi.Srivatsavai@Sun.COM       } else {
314*10491SRishi.Srivatsavai@Sun.COM         return;
315*10491SRishi.Srivatsavai@Sun.COM       }
316*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
317*10491SRishi.Srivatsavai@Sun.COM       if (port->info->debug)
318*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("BPDU_RSTP on port %s", port->port_name);
319*10491SRishi.Srivatsavai@Sun.COM #endif
320*10491SRishi.Srivatsavai@Sun.COM       break;
321*10491SRishi.Srivatsavai@Sun.COM   }
322*10491SRishi.Srivatsavai@Sun.COM 
323*10491SRishi.Srivatsavai@Sun.COM   port->msgBpduVersion = bpdu->hdr.version;
324*10491SRishi.Srivatsavai@Sun.COM   port->msgBpduType =    bpdu->hdr.bpdu_type;
325*10491SRishi.Srivatsavai@Sun.COM   port->msgFlags =       bpdu->body.flags;
326*10491SRishi.Srivatsavai@Sun.COM 
327*10491SRishi.Srivatsavai@Sun.COM   /* 17.18.11 */
328*10491SRishi.Srivatsavai@Sun.COM   STP_VECT_get_vector (&bpdu->body, &port->msgPrio);
329*10491SRishi.Srivatsavai@Sun.COM   port->msgPrio.bridge_port = port->port_id;
330*10491SRishi.Srivatsavai@Sun.COM 
331*10491SRishi.Srivatsavai@Sun.COM   /* 17.18.12 */
332*10491SRishi.Srivatsavai@Sun.COM   STP_get_times (&bpdu->body, &port->msgTimes);
333*10491SRishi.Srivatsavai@Sun.COM 
334*10491SRishi.Srivatsavai@Sun.COM   /* 17.18.25, 17.18.26 : see setTcFlags() */
335*10491SRishi.Srivatsavai@Sun.COM }
336*10491SRishi.Srivatsavai@Sun.COM 
STP_info_enter_state(STATE_MACH_T * this)337*10491SRishi.Srivatsavai@Sun.COM void STP_info_enter_state (STATE_MACH_T* this)
338*10491SRishi.Srivatsavai@Sun.COM {
339*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port = this->owner.port;
340*10491SRishi.Srivatsavai@Sun.COM 
341*10491SRishi.Srivatsavai@Sun.COM   switch (this->State) {
342*10491SRishi.Srivatsavai@Sun.COM     case BEGIN:
343*10491SRishi.Srivatsavai@Sun.COM       port->rcvdMsg = OtherMsg;
344*10491SRishi.Srivatsavai@Sun.COM       port->msgBpduType = (unsigned char)-1;
345*10491SRishi.Srivatsavai@Sun.COM       port->msgPortRole = RSTP_PORT_ROLE_UNKN;
346*10491SRishi.Srivatsavai@Sun.COM       port->msgFlags = 0;
347*10491SRishi.Srivatsavai@Sun.COM 
348*10491SRishi.Srivatsavai@Sun.COM       /* clear port statistics */
349*10491SRishi.Srivatsavai@Sun.COM       port->rx_cfg_bpdu_cnt =
350*10491SRishi.Srivatsavai@Sun.COM       port->rx_rstp_bpdu_cnt =
351*10491SRishi.Srivatsavai@Sun.COM       port->rx_tcn_bpdu_cnt = 0;
352*10491SRishi.Srivatsavai@Sun.COM       /* FALLTHRU */
353*10491SRishi.Srivatsavai@Sun.COM     case DISABLED:
354*10491SRishi.Srivatsavai@Sun.COM       port->rcvdBpdu = port->rcvdRSTP = port->rcvdSTP = False;
355*10491SRishi.Srivatsavai@Sun.COM       port->updtInfo = port->proposing = False; /* In DISABLED */
356*10491SRishi.Srivatsavai@Sun.COM       port->agreed = port->proposed = False;
357*10491SRishi.Srivatsavai@Sun.COM       port->rcvdInfoWhile = 0;
358*10491SRishi.Srivatsavai@Sun.COM       port->infoIs = Disabled;
359*10491SRishi.Srivatsavai@Sun.COM       port->reselect = True;
360*10491SRishi.Srivatsavai@Sun.COM       port->selected = False;
361*10491SRishi.Srivatsavai@Sun.COM       break;
362*10491SRishi.Srivatsavai@Sun.COM     case ENABLED: /* IEEE 802.1y, 17.21, Z.14 */
363*10491SRishi.Srivatsavai@Sun.COM       STP_VECT_copy (&port->portPrio, &port->designPrio);
364*10491SRishi.Srivatsavai@Sun.COM       STP_copy_times (&port->portTimes, &port->designTimes);
365*10491SRishi.Srivatsavai@Sun.COM       break;
366*10491SRishi.Srivatsavai@Sun.COM     case AGED:
367*10491SRishi.Srivatsavai@Sun.COM       port->infoIs = Aged;
368*10491SRishi.Srivatsavai@Sun.COM       port->reselect = True;
369*10491SRishi.Srivatsavai@Sun.COM       port->selected = False;
370*10491SRishi.Srivatsavai@Sun.COM       break;
371*10491SRishi.Srivatsavai@Sun.COM     case UPDATE:
372*10491SRishi.Srivatsavai@Sun.COM       STP_VECT_copy (&port->portPrio, &port->designPrio);
373*10491SRishi.Srivatsavai@Sun.COM       STP_copy_times (&port->portTimes, &port->designTimes);
374*10491SRishi.Srivatsavai@Sun.COM       port->updtInfo = False;
375*10491SRishi.Srivatsavai@Sun.COM       port->agreed = port->synced = False; /* In UPDATE */
376*10491SRishi.Srivatsavai@Sun.COM       port->proposed = port->proposing = False; /* in UPDATE */
377*10491SRishi.Srivatsavai@Sun.COM       port->infoIs = Mine;
378*10491SRishi.Srivatsavai@Sun.COM       port->newInfo = True;
379*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
380*10491SRishi.Srivatsavai@Sun.COM       if (this->debug) {
381*10491SRishi.Srivatsavai@Sun.COM         STP_VECT_br_id_print ("updated: portPrio.design_bridge",
382*10491SRishi.Srivatsavai@Sun.COM                             &port->portPrio.design_bridge, True);
383*10491SRishi.Srivatsavai@Sun.COM         STP_VECT_br_id_print ("updated:   portPrio.root_bridge",
384*10491SRishi.Srivatsavai@Sun.COM                             &port->portPrio.root_bridge, True);
385*10491SRishi.Srivatsavai@Sun.COM       }
386*10491SRishi.Srivatsavai@Sun.COM #endif
387*10491SRishi.Srivatsavai@Sun.COM       break;
388*10491SRishi.Srivatsavai@Sun.COM     case CURRENT:
389*10491SRishi.Srivatsavai@Sun.COM       break;
390*10491SRishi.Srivatsavai@Sun.COM     case RECEIVE:
391*10491SRishi.Srivatsavai@Sun.COM       port->rcvdMsg = rcvBpdu (this);
392*10491SRishi.Srivatsavai@Sun.COM       updtBPDUVersion (this);
393*10491SRishi.Srivatsavai@Sun.COM       setTcFlags (this);
394*10491SRishi.Srivatsavai@Sun.COM       port->rcvdBpdu = False;
395*10491SRishi.Srivatsavai@Sun.COM       break;
396*10491SRishi.Srivatsavai@Sun.COM     case SUPERIOR:
397*10491SRishi.Srivatsavai@Sun.COM       STP_VECT_copy (&port->portPrio, &port->msgPrio);
398*10491SRishi.Srivatsavai@Sun.COM       STP_copy_times (&port->portTimes, &port->msgTimes);
399*10491SRishi.Srivatsavai@Sun.COM       updtRcvdInfoWhile (this);
400*10491SRishi.Srivatsavai@Sun.COM #if 1 /* due 802.1y, Z.7 */
401*10491SRishi.Srivatsavai@Sun.COM       port->agreed = False; /* deleted due 802.y in SUPERIOR */
402*10491SRishi.Srivatsavai@Sun.COM       port->synced = False; /* due 802.y deleted in SUPERIOR */
403*10491SRishi.Srivatsavai@Sun.COM #endif
404*10491SRishi.Srivatsavai@Sun.COM       port->proposing = False; /* in SUPERIOR */
405*10491SRishi.Srivatsavai@Sun.COM       port->proposed = recordProposed (this, "SUPERIOR");
406*10491SRishi.Srivatsavai@Sun.COM       port->infoIs = Received;
407*10491SRishi.Srivatsavai@Sun.COM       port->reselect = True;
408*10491SRishi.Srivatsavai@Sun.COM       port->selected = False;
409*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
410*10491SRishi.Srivatsavai@Sun.COM       if (this->debug) {
411*10491SRishi.Srivatsavai@Sun.COM         STP_VECT_br_id_print ("stored: portPrio.design_bridge",
412*10491SRishi.Srivatsavai@Sun.COM                             &port->portPrio.design_bridge, True);
413*10491SRishi.Srivatsavai@Sun.COM         STP_VECT_br_id_print ("stored:   portPrio.root_bridge",
414*10491SRishi.Srivatsavai@Sun.COM                             &port->portPrio.root_bridge, True);
415*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("proposed=%d on port %s",
416*10491SRishi.Srivatsavai@Sun.COM                    (int) port->proposed, port->port_name);
417*10491SRishi.Srivatsavai@Sun.COM       }
418*10491SRishi.Srivatsavai@Sun.COM #endif
419*10491SRishi.Srivatsavai@Sun.COM       break;
420*10491SRishi.Srivatsavai@Sun.COM     case REPEAT:
421*10491SRishi.Srivatsavai@Sun.COM       port->proposed = recordProposed (this, "REPEAT");
422*10491SRishi.Srivatsavai@Sun.COM       updtRcvdInfoWhile (this);
423*10491SRishi.Srivatsavai@Sun.COM       break;
424*10491SRishi.Srivatsavai@Sun.COM   case AGREEMENT:
425*10491SRishi.Srivatsavai@Sun.COM #ifdef STP_DBG
426*10491SRishi.Srivatsavai@Sun.COM       if (port->roletrns->debug) {
427*10491SRishi.Srivatsavai@Sun.COM         stp_trace ("(%s-%s) rx AGREEMENT flag !",
428*10491SRishi.Srivatsavai@Sun.COM             port->owner->name, port->port_name);
429*10491SRishi.Srivatsavai@Sun.COM       }
430*10491SRishi.Srivatsavai@Sun.COM #endif
431*10491SRishi.Srivatsavai@Sun.COM 
432*10491SRishi.Srivatsavai@Sun.COM       port->agreed = True;
433*10491SRishi.Srivatsavai@Sun.COM       port->proposing = False; /* In AGREEMENT */
434*10491SRishi.Srivatsavai@Sun.COM       break;
435*10491SRishi.Srivatsavai@Sun.COM   }
436*10491SRishi.Srivatsavai@Sun.COM 
437*10491SRishi.Srivatsavai@Sun.COM }
438*10491SRishi.Srivatsavai@Sun.COM 
STP_info_check_conditions(STATE_MACH_T * this)439*10491SRishi.Srivatsavai@Sun.COM Bool STP_info_check_conditions (STATE_MACH_T* this)
440*10491SRishi.Srivatsavai@Sun.COM {
441*10491SRishi.Srivatsavai@Sun.COM   register PORT_T* port = this->owner.port;
442*10491SRishi.Srivatsavai@Sun.COM 
443*10491SRishi.Srivatsavai@Sun.COM   if ((! port->portEnabled && port->infoIs != Disabled) || BEGIN == this->State) {
444*10491SRishi.Srivatsavai@Sun.COM     return STP_hop_2_state (this, DISABLED);
445*10491SRishi.Srivatsavai@Sun.COM   }
446*10491SRishi.Srivatsavai@Sun.COM 
447*10491SRishi.Srivatsavai@Sun.COM   switch (this->State) {
448*10491SRishi.Srivatsavai@Sun.COM     case DISABLED:
449*10491SRishi.Srivatsavai@Sun.COM       if (port->updtInfo) {
450*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DISABLED);
451*10491SRishi.Srivatsavai@Sun.COM       }
452*10491SRishi.Srivatsavai@Sun.COM       if (port->portEnabled && port->selected) {
453*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, ENABLED);
454*10491SRishi.Srivatsavai@Sun.COM       }
455*10491SRishi.Srivatsavai@Sun.COM       if (port->rcvdBpdu) {
456*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, DISABLED);
457*10491SRishi.Srivatsavai@Sun.COM       }
458*10491SRishi.Srivatsavai@Sun.COM       break;
459*10491SRishi.Srivatsavai@Sun.COM     case ENABLED: /* IEEE 802.1y, 17.21, Z.14 */
460*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, AGED);
461*10491SRishi.Srivatsavai@Sun.COM       break;
462*10491SRishi.Srivatsavai@Sun.COM     case AGED:
463*10491SRishi.Srivatsavai@Sun.COM       if (port->selected && port->updtInfo) {
464*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, UPDATE);
465*10491SRishi.Srivatsavai@Sun.COM       }
466*10491SRishi.Srivatsavai@Sun.COM       break;
467*10491SRishi.Srivatsavai@Sun.COM     case UPDATE:
468*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, CURRENT);
469*10491SRishi.Srivatsavai@Sun.COM       break;
470*10491SRishi.Srivatsavai@Sun.COM     case CURRENT:
471*10491SRishi.Srivatsavai@Sun.COM       if (port->selected && port->updtInfo) {
472*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, UPDATE);
473*10491SRishi.Srivatsavai@Sun.COM       }
474*10491SRishi.Srivatsavai@Sun.COM 
475*10491SRishi.Srivatsavai@Sun.COM       if (Received == port->infoIs       &&
476*10491SRishi.Srivatsavai@Sun.COM           ! port->rcvdInfoWhile &&
477*10491SRishi.Srivatsavai@Sun.COM           ! port->updtInfo               &&
478*10491SRishi.Srivatsavai@Sun.COM           ! port->rcvdBpdu) {
479*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, AGED);
480*10491SRishi.Srivatsavai@Sun.COM       }
481*10491SRishi.Srivatsavai@Sun.COM       if (port->rcvdBpdu && !port->updtInfo) {
482*10491SRishi.Srivatsavai@Sun.COM         return STP_hop_2_state (this, RECEIVE);
483*10491SRishi.Srivatsavai@Sun.COM       }
484*10491SRishi.Srivatsavai@Sun.COM       break;
485*10491SRishi.Srivatsavai@Sun.COM     case RECEIVE:
486*10491SRishi.Srivatsavai@Sun.COM       switch (port->rcvdMsg) {
487*10491SRishi.Srivatsavai@Sun.COM         case SuperiorDesignateMsg:
488*10491SRishi.Srivatsavai@Sun.COM           return STP_hop_2_state (this, SUPERIOR);
489*10491SRishi.Srivatsavai@Sun.COM         case RepeatedDesignateMsg:
490*10491SRishi.Srivatsavai@Sun.COM           return STP_hop_2_state (this, REPEAT);
491*10491SRishi.Srivatsavai@Sun.COM         case ConfirmedRootMsg:
492*10491SRishi.Srivatsavai@Sun.COM           return STP_hop_2_state (this, AGREEMENT);
493*10491SRishi.Srivatsavai@Sun.COM         default:
494*10491SRishi.Srivatsavai@Sun.COM           return STP_hop_2_state (this, CURRENT);
495*10491SRishi.Srivatsavai@Sun.COM       }
496*10491SRishi.Srivatsavai@Sun.COM       break;
497*10491SRishi.Srivatsavai@Sun.COM     case SUPERIOR:
498*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, CURRENT);
499*10491SRishi.Srivatsavai@Sun.COM       break;
500*10491SRishi.Srivatsavai@Sun.COM     case REPEAT:
501*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, CURRENT);
502*10491SRishi.Srivatsavai@Sun.COM       break;
503*10491SRishi.Srivatsavai@Sun.COM     case AGREEMENT:
504*10491SRishi.Srivatsavai@Sun.COM       return STP_hop_2_state (this, CURRENT);
505*10491SRishi.Srivatsavai@Sun.COM       break;
506*10491SRishi.Srivatsavai@Sun.COM   }
507*10491SRishi.Srivatsavai@Sun.COM 
508*10491SRishi.Srivatsavai@Sun.COM   return False;
509*10491SRishi.Srivatsavai@Sun.COM }
510