1 /* $OpenBSD: bridgestp.c,v 1.75 2020/07/30 11:32:06 mvs Exp $ */ 2 3 /* 4 * Copyright (c) 2000 Jason L. Wright (jason@thought.net) 5 * Copyright (c) 2006 Andrew Thompson (thompsa@FreeBSD.org) 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * Implementation of the spanning tree protocol as defined in 32 * ISO/IEC 802.1D-2004, June 9, 2004. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/mbuf.h> 38 #include <sys/socket.h> 39 #include <sys/ioctl.h> 40 #include <sys/device.h> 41 #include <sys/kernel.h> 42 #include <sys/timeout.h> 43 44 #include <net/if.h> 45 #include <net/if_types.h> 46 #include <net/if_dl.h> 47 #include <net/if_llc.h> 48 #include <net/netisr.h> 49 50 #include <netinet/in.h> 51 #include <netinet/ip.h> 52 #include <netinet/if_ether.h> 53 54 #include <net/if_bridge.h> 55 56 /* STP port states */ 57 #define BSTP_IFSTATE_DISABLED 0 58 #define BSTP_IFSTATE_LISTENING 1 59 #define BSTP_IFSTATE_LEARNING 2 60 #define BSTP_IFSTATE_FORWARDING 3 61 #define BSTP_IFSTATE_BLOCKING 4 62 #define BSTP_IFSTATE_DISCARDING 5 63 64 #define BSTP_TCSTATE_ACTIVE 1 65 #define BSTP_TCSTATE_DETECTED 2 66 #define BSTP_TCSTATE_INACTIVE 3 67 #define BSTP_TCSTATE_LEARNING 4 68 #define BSTP_TCSTATE_PROPAG 5 69 #define BSTP_TCSTATE_ACK 6 70 #define BSTP_TCSTATE_TC 7 71 #define BSTP_TCSTATE_TCN 8 72 73 #define BSTP_ROLE_DISABLED 0 74 #define BSTP_ROLE_ROOT 1 75 #define BSTP_ROLE_DESIGNATED 2 76 #define BSTP_ROLE_ALTERNATE 3 77 #define BSTP_ROLE_BACKUP 4 78 79 /* STP port flags */ 80 #define BSTP_PORT_CANMIGRATE 0x0001 81 #define BSTP_PORT_NEWINFO 0x0002 82 #define BSTP_PORT_DISPUTED 0x0004 83 #define BSTP_PORT_ADMCOST 0x0008 84 #define BSTP_PORT_AUTOEDGE 0x0010 85 86 /* BPDU priority */ 87 #define BSTP_PDU_SUPERIOR 1 88 #define BSTP_PDU_REPEATED 2 89 #define BSTP_PDU_INFERIOR 3 90 #define BSTP_PDU_INFERIORALT 4 91 #define BSTP_PDU_OTHER 5 92 93 /* BPDU flags */ 94 #define BSTP_PDU_PRMASK 0x0c /* Port Role */ 95 #define BSTP_PDU_PRSHIFT 2 /* Port Role offset */ 96 #define BSTP_PDU_F_UNKN 0x00 /* Unknown port (00) */ 97 #define BSTP_PDU_F_ALT 0x01 /* Alt/Backup port (01) */ 98 #define BSTP_PDU_F_ROOT 0x02 /* Root port (10) */ 99 #define BSTP_PDU_F_DESG 0x03 /* Designated port (11) */ 100 101 #define BSTP_PDU_STPMASK 0x81 /* strip unused STP flags */ 102 #define BSTP_PDU_RSTPMASK 0x7f /* strip unused RSTP flags */ 103 #define BSTP_PDU_F_TC 0x01 /* Topology change */ 104 #define BSTP_PDU_F_P 0x02 /* Proposal flag */ 105 #define BSTP_PDU_F_L 0x10 /* Learning flag */ 106 #define BSTP_PDU_F_F 0x20 /* Forwarding flag */ 107 #define BSTP_PDU_F_A 0x40 /* Agreement flag */ 108 #define BSTP_PDU_F_TCA 0x80 /* Topology change ack */ 109 110 /* 111 * Spanning tree defaults. 112 */ 113 #define BSTP_DEFAULT_MAX_AGE (20 * 256) 114 #define BSTP_DEFAULT_HELLO_TIME (2 * 256) 115 #define BSTP_DEFAULT_FORWARD_DELAY (15 * 256) 116 #define BSTP_DEFAULT_HOLD_TIME (1 * 256) 117 #define BSTP_DEFAULT_MIGRATE_DELAY (3 * 256) 118 #define BSTP_DEFAULT_HOLD_COUNT 6 119 #define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000 120 #define BSTP_DEFAULT_PORT_PRIORITY 0x80 121 #define BSTP_DEFAULT_PATH_COST 55 122 #define BSTP_MIN_HELLO_TIME (1 * 256) 123 #define BSTP_MIN_MAX_AGE (6 * 256) 124 #define BSTP_MIN_FORWARD_DELAY (4 * 256) 125 #define BSTP_MIN_HOLD_COUNT 1 126 #define BSTP_MAX_HELLO_TIME (2 * 256) 127 #define BSTP_MAX_MAX_AGE (40 * 256) 128 #define BSTP_MAX_FORWARD_DELAY (30 * 256) 129 #define BSTP_MAX_HOLD_COUNT 10 130 #define BSTP_MAX_PRIORITY 61440 131 #define BSTP_MAX_PORT_PRIORITY 240 132 #define BSTP_MAX_PATH_COST 200000000 133 134 /* BPDU message types */ 135 #define BSTP_MSGTYPE_CFG 0x00 /* Configuration */ 136 #define BSTP_MSGTYPE_RSTP 0x02 /* Rapid STP */ 137 #define BSTP_MSGTYPE_TCN 0x80 /* Topology chg notification */ 138 139 #define BSTP_INFO_RECEIVED 1 140 #define BSTP_INFO_MINE 2 141 #define BSTP_INFO_AGED 3 142 #define BSTP_INFO_DISABLED 4 143 144 #define BSTP_MESSAGE_AGE_INCR (1 * 256) /* in 256ths of a second */ 145 #define BSTP_TICK_VAL (1 * 256) /* in 256ths of a second */ 146 #define BSTP_LINK_TIMER (BSTP_TICK_VAL * 15) 147 148 #ifdef BRIDGESTP_DEBUG 149 #define DPRINTF(bp, fmt, arg...) \ 150 do { \ 151 struct ifnet *__ifp = if_get((bp)->bp_ifindex); \ 152 printf("bstp: %s" fmt, __ifp? __ifp->if_xname : "Unknown", ##arg); \ 153 if_put(__ifp); \ 154 } while (0) 155 #else 156 #define DPRINTF(bp, fmt, arg...) 157 #endif 158 159 #define PV2ADDR(pv, eaddr) do { \ 160 eaddr[0] = pv >> 40; \ 161 eaddr[1] = pv >> 32; \ 162 eaddr[2] = pv >> 24; \ 163 eaddr[3] = pv >> 16; \ 164 eaddr[4] = pv >> 8; \ 165 eaddr[5] = pv >> 0; \ 166 } while (0) 167 168 #define INFO_BETTER 1 169 #define INFO_SAME 0 170 #define INFO_WORSE -1 171 172 #define BSTP_IFQ_PRIO 6 173 174 /* 175 * Because BPDU's do not make nicely aligned structures, two different 176 * declarations are used: bstp_?bpdu (wire representation, packed) and 177 * bstp_*_unit (internal, nicely aligned version). 178 */ 179 180 /* configuration bridge protocol data unit */ 181 struct bstp_cbpdu { 182 u_int8_t cbu_dsap; /* LLC: destination sap */ 183 u_int8_t cbu_ssap; /* LLC: source sap */ 184 u_int8_t cbu_ctl; /* LLC: control */ 185 u_int16_t cbu_protoid; /* protocol id */ 186 u_int8_t cbu_protover; /* protocol version */ 187 u_int8_t cbu_bpdutype; /* message type */ 188 u_int8_t cbu_flags; /* flags (below) */ 189 190 /* root id */ 191 u_int16_t cbu_rootpri; /* root priority */ 192 u_int8_t cbu_rootaddr[6]; /* root address */ 193 194 u_int32_t cbu_rootpathcost; /* root path cost */ 195 196 /* bridge id */ 197 u_int16_t cbu_bridgepri; /* bridge priority */ 198 u_int8_t cbu_bridgeaddr[6]; /* bridge address */ 199 200 u_int16_t cbu_portid; /* port id */ 201 u_int16_t cbu_messageage; /* current message age */ 202 u_int16_t cbu_maxage; /* maximum age */ 203 u_int16_t cbu_hellotime; /* hello time */ 204 u_int16_t cbu_forwarddelay; /* forwarding delay */ 205 u_int8_t cbu_versionlen; /* version 1 length */ 206 } __packed; 207 208 #define BSTP_BPDU_STP_LEN (3 + 35) /* LLC + STP pdu */ 209 #define BSTP_BPDU_RSTP_LEN (3 + 36) /* LLC + RSTP pdu */ 210 211 /* topology change notification bridge protocol data unit */ 212 struct bstp_tbpdu { 213 u_int8_t tbu_dsap; /* LLC: destination sap */ 214 u_int8_t tbu_ssap; /* LLC: source sap */ 215 u_int8_t tbu_ctl; /* LLC: control */ 216 u_int16_t tbu_protoid; /* protocol id */ 217 u_int8_t tbu_protover; /* protocol version */ 218 u_int8_t tbu_bpdutype; /* message type */ 219 } __packed; 220 221 const u_int8_t bstp_etheraddr[] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; 222 223 224 void bstp_transmit(struct bstp_state *, struct bstp_port *); 225 void bstp_transmit_bpdu(struct bstp_state *, struct bstp_port *); 226 void bstp_transmit_tcn(struct bstp_state *, struct bstp_port *); 227 void bstp_decode_bpdu(struct bstp_port *, struct bstp_cbpdu *, 228 struct bstp_config_unit *); 229 void bstp_send_bpdu(struct bstp_state *, struct bstp_port *, 230 struct bstp_cbpdu *); 231 int bstp_pdu_flags(struct bstp_port *); 232 void bstp_received_stp(struct bstp_state *, struct bstp_port *, 233 struct mbuf **, struct bstp_tbpdu *); 234 void bstp_received_rstp(struct bstp_state *, struct bstp_port *, 235 struct mbuf **, struct bstp_tbpdu *); 236 void bstp_received_tcn(struct bstp_state *, struct bstp_port *, 237 struct bstp_tcn_unit *); 238 void bstp_received_bpdu(struct bstp_state *, struct bstp_port *, 239 struct bstp_config_unit *); 240 int bstp_pdu_rcvtype(struct bstp_port *, struct bstp_config_unit *); 241 int bstp_pdu_bettersame(struct bstp_port *, int); 242 int bstp_info_cmp(struct bstp_pri_vector *, 243 struct bstp_pri_vector *); 244 int bstp_info_superior(struct bstp_pri_vector *, 245 struct bstp_pri_vector *); 246 void bstp_assign_roles(struct bstp_state *); 247 void bstp_update_roles(struct bstp_state *, struct bstp_port *); 248 void bstp_update_state(struct bstp_state *, struct bstp_port *); 249 void bstp_update_tc(struct bstp_port *); 250 void bstp_update_info(struct bstp_port *); 251 void bstp_set_other_tcprop(struct bstp_port *); 252 void bstp_set_all_reroot(struct bstp_state *); 253 void bstp_set_all_sync(struct bstp_state *); 254 void bstp_set_port_state(struct bstp_port *, int); 255 void bstp_set_port_role(struct bstp_port *, int); 256 void bstp_set_port_proto(struct bstp_port *, int); 257 void bstp_set_port_tc(struct bstp_port *, int); 258 void bstp_set_timer_tc(struct bstp_port *); 259 void bstp_set_timer_msgage(struct bstp_port *); 260 void bstp_reset(struct bstp_state *); 261 int bstp_rerooted(struct bstp_state *, struct bstp_port *); 262 u_int32_t bstp_calc_path_cost(struct bstp_port *); 263 void bstp_notify_rtage(struct bstp_port *, int); 264 void bstp_ifupdstatus(struct bstp_state *, struct bstp_port *); 265 void bstp_enable_port(struct bstp_state *, struct bstp_port *); 266 void bstp_disable_port(struct bstp_state *, struct bstp_port *); 267 void bstp_tick(void *); 268 void bstp_timer_start(struct bstp_timer *, u_int16_t); 269 void bstp_timer_stop(struct bstp_timer *); 270 void bstp_timer_latch(struct bstp_timer *); 271 int bstp_timer_expired(struct bstp_timer *); 272 void bstp_hello_timer_expiry(struct bstp_state *, 273 struct bstp_port *); 274 void bstp_message_age_expiry(struct bstp_state *, 275 struct bstp_port *); 276 void bstp_migrate_delay_expiry(struct bstp_state *, 277 struct bstp_port *); 278 void bstp_edge_delay_expiry(struct bstp_state *, 279 struct bstp_port *); 280 int bstp_addr_cmp(const u_int8_t *, const u_int8_t *); 281 int bstp_same_bridgeid(u_int64_t, u_int64_t); 282 283 284 void 285 bstp_transmit(struct bstp_state *bs, struct bstp_port *bp) 286 { 287 struct ifnet *ifp; 288 289 if ((ifp = if_get(bs->bs_ifindex)) == NULL) 290 return; 291 292 if ((ifp->if_flags & IFF_RUNNING) == 0 || bp == NULL) { 293 if_put(ifp); 294 return; 295 } 296 if_put(ifp); 297 298 /* 299 * a PDU can only be sent if we have tx quota left and the 300 * hello timer is running. 301 */ 302 if (bp->bp_hello_timer.active == 0) { 303 /* Test if it needs to be reset */ 304 bstp_hello_timer_expiry(bs, bp); 305 return; 306 } 307 if (bp->bp_txcount > bs->bs_txholdcount) 308 /* Ran out of karma */ 309 return; 310 311 if (bp->bp_protover == BSTP_PROTO_RSTP) { 312 bstp_transmit_bpdu(bs, bp); 313 bp->bp_tc_ack = 0; 314 } else { /* STP */ 315 switch (bp->bp_role) { 316 case BSTP_ROLE_DESIGNATED: 317 bstp_transmit_bpdu(bs, bp); 318 bp->bp_tc_ack = 0; 319 break; 320 321 case BSTP_ROLE_ROOT: 322 bstp_transmit_tcn(bs, bp); 323 break; 324 } 325 } 326 bstp_timer_start(&bp->bp_hello_timer, bp->bp_desg_htime); 327 bp->bp_flags &= ~BSTP_PORT_NEWINFO; 328 } 329 330 void 331 bstp_transmit_bpdu(struct bstp_state *bs, struct bstp_port *bp) 332 { 333 struct bstp_cbpdu bpdu; 334 335 bpdu.cbu_rootpri = htons(bp->bp_desg_pv.pv_root_id >> 48); 336 PV2ADDR(bp->bp_desg_pv.pv_root_id, bpdu.cbu_rootaddr); 337 338 bpdu.cbu_rootpathcost = htonl(bp->bp_desg_pv.pv_cost); 339 340 bpdu.cbu_bridgepri = htons(bp->bp_desg_pv.pv_dbridge_id >> 48); 341 PV2ADDR(bp->bp_desg_pv.pv_dbridge_id, bpdu.cbu_bridgeaddr); 342 343 bpdu.cbu_portid = htons(bp->bp_port_id); 344 bpdu.cbu_messageage = htons(bp->bp_desg_msg_age); 345 bpdu.cbu_maxage = htons(bp->bp_desg_max_age); 346 bpdu.cbu_hellotime = htons(bp->bp_desg_htime); 347 bpdu.cbu_forwarddelay = htons(bp->bp_desg_fdelay); 348 349 bpdu.cbu_flags = bstp_pdu_flags(bp); 350 351 switch (bp->bp_protover) { 352 case BSTP_PROTO_STP: 353 bpdu.cbu_bpdutype = BSTP_MSGTYPE_CFG; 354 break; 355 case BSTP_PROTO_RSTP: 356 bpdu.cbu_bpdutype = BSTP_MSGTYPE_RSTP; 357 break; 358 } 359 360 bstp_send_bpdu(bs, bp, &bpdu); 361 } 362 363 void 364 bstp_transmit_tcn(struct bstp_state *bs, struct bstp_port *bp) 365 { 366 struct bstp_tbpdu bpdu; 367 struct ifnet *ifp; 368 struct ether_header *eh; 369 struct mbuf *m; 370 371 if ((ifp = if_get(bp->bp_ifindex)) == NULL) 372 return; 373 if ((ifp->if_flags & IFF_RUNNING) == 0) 374 goto rele; 375 376 MGETHDR(m, M_DONTWAIT, MT_DATA); 377 if (m == NULL) 378 goto rele; 379 m->m_pkthdr.ph_ifidx = ifp->if_index; 380 m->m_pkthdr.len = sizeof(*eh) + sizeof(bpdu); 381 m->m_pkthdr.pf.prio = BSTP_IFQ_PRIO; 382 m->m_len = m->m_pkthdr.len; 383 384 eh = mtod(m, struct ether_header *); 385 bcopy(LLADDR(ifp->if_sadl), eh->ether_shost, ETHER_ADDR_LEN); 386 bcopy(bstp_etheraddr, eh->ether_dhost, ETHER_ADDR_LEN); 387 eh->ether_type = htons(sizeof(bpdu)); 388 389 bpdu.tbu_ssap = bpdu.tbu_dsap = LLC_8021D_LSAP; 390 bpdu.tbu_ctl = LLC_UI; 391 bpdu.tbu_protoid = 0; 392 bpdu.tbu_protover = 0; 393 bpdu.tbu_bpdutype = BSTP_MSGTYPE_TCN; 394 bcopy(&bpdu, mtod(m, caddr_t) + sizeof(*eh), sizeof(bpdu)); 395 396 bp->bp_txcount++; 397 if_enqueue(ifp, m); 398 rele: 399 if_put(ifp); 400 } 401 402 void 403 bstp_decode_bpdu(struct bstp_port *bp, struct bstp_cbpdu *cpdu, 404 struct bstp_config_unit *cu) 405 { 406 int flags; 407 408 cu->cu_pv.pv_root_id = 409 (((u_int64_t)ntohs(cpdu->cbu_rootpri)) << 48) | 410 (((u_int64_t)cpdu->cbu_rootaddr[0]) << 40) | 411 (((u_int64_t)cpdu->cbu_rootaddr[1]) << 32) | 412 (((u_int64_t)cpdu->cbu_rootaddr[2]) << 24) | 413 (((u_int64_t)cpdu->cbu_rootaddr[3]) << 16) | 414 (((u_int64_t)cpdu->cbu_rootaddr[4]) << 8) | 415 (((u_int64_t)cpdu->cbu_rootaddr[5]) << 0); 416 417 cu->cu_pv.pv_dbridge_id = 418 (((u_int64_t)ntohs(cpdu->cbu_bridgepri)) << 48) | 419 (((u_int64_t)cpdu->cbu_bridgeaddr[0]) << 40) | 420 (((u_int64_t)cpdu->cbu_bridgeaddr[1]) << 32) | 421 (((u_int64_t)cpdu->cbu_bridgeaddr[2]) << 24) | 422 (((u_int64_t)cpdu->cbu_bridgeaddr[3]) << 16) | 423 (((u_int64_t)cpdu->cbu_bridgeaddr[4]) << 8) | 424 (((u_int64_t)cpdu->cbu_bridgeaddr[5]) << 0); 425 426 cu->cu_pv.pv_cost = ntohl(cpdu->cbu_rootpathcost); 427 cu->cu_message_age = ntohs(cpdu->cbu_messageage); 428 cu->cu_max_age = ntohs(cpdu->cbu_maxage); 429 cu->cu_hello_time = ntohs(cpdu->cbu_hellotime); 430 cu->cu_forward_delay = ntohs(cpdu->cbu_forwarddelay); 431 cu->cu_pv.pv_dport_id = ntohs(cpdu->cbu_portid); 432 cu->cu_pv.pv_port_id = bp->bp_port_id; 433 cu->cu_message_type = cpdu->cbu_bpdutype; 434 435 /* Strip off unused flags in STP mode */ 436 flags = cpdu->cbu_flags; 437 switch (cpdu->cbu_protover) { 438 case BSTP_PROTO_STP: 439 flags &= BSTP_PDU_STPMASK; 440 /* A STP BPDU explicitly conveys a Designated Port */ 441 cu->cu_role = BSTP_ROLE_DESIGNATED; 442 break; 443 case BSTP_PROTO_RSTP: 444 flags &= BSTP_PDU_RSTPMASK; 445 break; 446 } 447 448 cu->cu_topology_change_ack = 449 (flags & BSTP_PDU_F_TCA) ? 1 : 0; 450 cu->cu_proposal = 451 (flags & BSTP_PDU_F_P) ? 1 : 0; 452 cu->cu_agree = 453 (flags & BSTP_PDU_F_A) ? 1 : 0; 454 cu->cu_learning = 455 (flags & BSTP_PDU_F_L) ? 1 : 0; 456 cu->cu_forwarding = 457 (flags & BSTP_PDU_F_F) ? 1 : 0; 458 cu->cu_topology_change = 459 (flags & BSTP_PDU_F_TC) ? 1 : 0; 460 461 switch ((flags & BSTP_PDU_PRMASK) >> BSTP_PDU_PRSHIFT) { 462 case BSTP_PDU_F_ROOT: 463 cu->cu_role = BSTP_ROLE_ROOT; 464 break; 465 case BSTP_PDU_F_ALT: 466 cu->cu_role = BSTP_ROLE_ALTERNATE; 467 break; 468 case BSTP_PDU_F_DESG: 469 cu->cu_role = BSTP_ROLE_DESIGNATED; 470 break; 471 } 472 } 473 474 void 475 bstp_send_bpdu(struct bstp_state *bs, struct bstp_port *bp, 476 struct bstp_cbpdu *bpdu) 477 { 478 struct ifnet *ifp; 479 struct mbuf *m; 480 struct ether_header *eh; 481 int s; 482 483 s = splnet(); 484 if ((ifp = if_get(bp->bp_ifindex)) == NULL) 485 goto done; 486 if ((ifp->if_flags & IFF_RUNNING) == 0) 487 goto rele; 488 489 MGETHDR(m, M_DONTWAIT, MT_DATA); 490 if (m == NULL) 491 goto rele; 492 493 eh = mtod(m, struct ether_header *); 494 495 bpdu->cbu_ssap = bpdu->cbu_dsap = LLC_8021D_LSAP; 496 bpdu->cbu_ctl = LLC_UI; 497 bpdu->cbu_protoid = htons(BSTP_PROTO_ID); 498 499 memcpy(eh->ether_shost, LLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 500 memcpy(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN); 501 502 switch (bpdu->cbu_bpdutype) { 503 case BSTP_MSGTYPE_CFG: 504 bpdu->cbu_protover = BSTP_PROTO_STP; 505 m->m_pkthdr.len = sizeof(*eh) + BSTP_BPDU_STP_LEN; 506 eh->ether_type = htons(BSTP_BPDU_STP_LEN); 507 memcpy(mtod(m, caddr_t) + sizeof(*eh), bpdu, 508 BSTP_BPDU_STP_LEN); 509 break; 510 case BSTP_MSGTYPE_RSTP: 511 bpdu->cbu_protover = BSTP_PROTO_RSTP; 512 bpdu->cbu_versionlen = htons(0); 513 m->m_pkthdr.len = sizeof(*eh) + BSTP_BPDU_RSTP_LEN; 514 eh->ether_type = htons(BSTP_BPDU_RSTP_LEN); 515 memcpy(mtod(m, caddr_t) + sizeof(*eh), bpdu, 516 BSTP_BPDU_RSTP_LEN); 517 break; 518 default: 519 panic("not implemented"); 520 } 521 m->m_pkthdr.ph_ifidx = ifp->if_index; 522 m->m_len = m->m_pkthdr.len; 523 m->m_pkthdr.pf.prio = BSTP_IFQ_PRIO; 524 525 bp->bp_txcount++; 526 if_enqueue(ifp, m); 527 rele: 528 if_put(ifp); 529 done: 530 splx(s); 531 } 532 533 int 534 bstp_pdu_flags(struct bstp_port *bp) 535 { 536 int flags = 0; 537 538 if (bp->bp_proposing && bp->bp_state != BSTP_IFSTATE_FORWARDING) 539 flags |= BSTP_PDU_F_P; 540 541 if (bp->bp_agree) 542 flags |= BSTP_PDU_F_A; 543 544 if (bp->bp_tc_timer.active) 545 flags |= BSTP_PDU_F_TC; 546 547 if (bp->bp_tc_ack) 548 flags |= BSTP_PDU_F_TCA; 549 550 switch (bp->bp_state) { 551 case BSTP_IFSTATE_LEARNING: 552 flags |= BSTP_PDU_F_L; 553 break; 554 case BSTP_IFSTATE_FORWARDING: 555 flags |= (BSTP_PDU_F_L | BSTP_PDU_F_F); 556 break; 557 } 558 559 switch (bp->bp_role) { 560 case BSTP_ROLE_ROOT: 561 flags |= (BSTP_PDU_F_ROOT << BSTP_PDU_PRSHIFT); 562 break; 563 case BSTP_ROLE_ALTERNATE: 564 case BSTP_ROLE_BACKUP: 565 flags |= (BSTP_PDU_F_ALT << BSTP_PDU_PRSHIFT); 566 break; 567 case BSTP_ROLE_DESIGNATED: 568 flags |= (BSTP_PDU_F_DESG << BSTP_PDU_PRSHIFT); 569 break; 570 } 571 572 /* Strip off unused flags in either mode */ 573 switch (bp->bp_protover) { 574 case BSTP_PROTO_STP: 575 flags &= BSTP_PDU_STPMASK; 576 break; 577 case BSTP_PROTO_RSTP: 578 flags &= BSTP_PDU_RSTPMASK; 579 break; 580 } 581 return (flags); 582 } 583 584 struct mbuf * 585 bstp_input(struct bstp_state *bs, struct bstp_port *bp, 586 struct ether_header *eh, struct mbuf *m) 587 { 588 struct bstp_tbpdu tpdu; 589 u_int16_t len; 590 591 if (bs == NULL || bp == NULL || bp->bp_active == 0) 592 return (m); 593 594 len = ntohs(eh->ether_type); 595 if (len < sizeof(tpdu)) 596 goto out; 597 598 m_adj(m, ETHER_HDR_LEN); 599 600 if (m->m_pkthdr.len > len) 601 m_adj(m, len - m->m_pkthdr.len); 602 if ((m = m_pullup(m, sizeof(tpdu))) == NULL) 603 goto out; 604 bcopy(mtod(m, struct tpdu *), &tpdu, sizeof(tpdu)); 605 606 if (tpdu.tbu_dsap != LLC_8021D_LSAP || 607 tpdu.tbu_ssap != LLC_8021D_LSAP || 608 tpdu.tbu_ctl != LLC_UI) 609 goto out; 610 if (tpdu.tbu_protoid != BSTP_PROTO_ID) 611 goto out; 612 613 /* 614 * We can treat later versions of the PDU as the same as the maximum 615 * version we implement. All additional parameters/flags are ignored. 616 */ 617 if (tpdu.tbu_protover > BSTP_PROTO_MAX) 618 tpdu.tbu_protover = BSTP_PROTO_MAX; 619 620 if (tpdu.tbu_protover != bp->bp_protover) { 621 /* 622 * Wait for the migration delay timer to expire before changing 623 * protocol version to avoid flip-flops. 624 */ 625 if (bp->bp_flags & BSTP_PORT_CANMIGRATE) 626 bstp_set_port_proto(bp, tpdu.tbu_protover); 627 else 628 goto out; 629 } 630 631 /* Clear operedge upon receiving a PDU on the port */ 632 bp->bp_operedge = 0; 633 bstp_timer_start(&bp->bp_edge_delay_timer, 634 BSTP_DEFAULT_MIGRATE_DELAY); 635 636 switch (tpdu.tbu_protover) { 637 case BSTP_PROTO_STP: 638 bstp_received_stp(bs, bp, &m, &tpdu); 639 break; 640 case BSTP_PROTO_RSTP: 641 bstp_received_rstp(bs, bp, &m, &tpdu); 642 break; 643 } 644 out: 645 m_freem(m); 646 return (NULL); 647 } 648 649 void 650 bstp_received_stp(struct bstp_state *bs, struct bstp_port *bp, 651 struct mbuf **mp, struct bstp_tbpdu *tpdu) 652 { 653 struct bstp_cbpdu cpdu; 654 struct bstp_config_unit *cu = &bp->bp_msg_cu; 655 struct bstp_tcn_unit tu; 656 657 switch (tpdu->tbu_bpdutype) { 658 case BSTP_MSGTYPE_TCN: 659 tu.tu_message_type = tpdu->tbu_bpdutype; 660 bstp_received_tcn(bs, bp, &tu); 661 break; 662 case BSTP_MSGTYPE_CFG: 663 if ((*mp)->m_len < BSTP_BPDU_STP_LEN && 664 (*mp = m_pullup(*mp, BSTP_BPDU_STP_LEN)) == NULL) 665 return; 666 memcpy(&cpdu, mtod(*mp, caddr_t), BSTP_BPDU_STP_LEN); 667 668 bstp_decode_bpdu(bp, &cpdu, cu); 669 bstp_received_bpdu(bs, bp, cu); 670 break; 671 } 672 } 673 674 void 675 bstp_received_rstp(struct bstp_state *bs, struct bstp_port *bp, 676 struct mbuf **mp, struct bstp_tbpdu *tpdu) 677 { 678 struct bstp_cbpdu cpdu; 679 struct bstp_config_unit *cu = &bp->bp_msg_cu; 680 681 if (tpdu->tbu_bpdutype != BSTP_MSGTYPE_RSTP) 682 return; 683 684 if ((*mp)->m_len < BSTP_BPDU_RSTP_LEN && 685 (*mp = m_pullup(*mp, BSTP_BPDU_RSTP_LEN)) == NULL) 686 return; 687 memcpy(&cpdu, mtod(*mp, caddr_t), BSTP_BPDU_RSTP_LEN); 688 689 bstp_decode_bpdu(bp, &cpdu, cu); 690 bstp_received_bpdu(bs, bp, cu); 691 } 692 693 void 694 bstp_received_tcn(struct bstp_state *bs, struct bstp_port *bp, 695 struct bstp_tcn_unit *tcn) 696 { 697 bp->bp_rcvdtcn = 1; 698 bstp_update_tc(bp); 699 } 700 701 void 702 bstp_received_bpdu(struct bstp_state *bs, struct bstp_port *bp, 703 struct bstp_config_unit *cu) 704 { 705 int type; 706 707 /* We need to have transitioned to INFO_MINE before proceeding */ 708 switch (bp->bp_infois) { 709 case BSTP_INFO_DISABLED: 710 case BSTP_INFO_AGED: 711 return; 712 } 713 714 type = bstp_pdu_rcvtype(bp, cu); 715 716 switch (type) { 717 case BSTP_PDU_SUPERIOR: 718 bs->bs_allsynced = 0; 719 bp->bp_agreed = 0; 720 bp->bp_proposing = 0; 721 722 if (cu->cu_proposal && cu->cu_forwarding == 0) 723 bp->bp_proposed = 1; 724 if (cu->cu_topology_change) 725 bp->bp_rcvdtc = 1; 726 if (cu->cu_topology_change_ack) 727 bp->bp_rcvdtca = 1; 728 729 if (bp->bp_agree && 730 !bstp_pdu_bettersame(bp, BSTP_INFO_RECEIVED)) 731 bp->bp_agree = 0; 732 733 /* copy the received priority and timers to the port */ 734 bp->bp_port_pv = cu->cu_pv; 735 bp->bp_port_msg_age = cu->cu_message_age; 736 bp->bp_port_max_age = cu->cu_max_age; 737 bp->bp_port_fdelay = cu->cu_forward_delay; 738 bp->bp_port_htime = 739 (cu->cu_hello_time > BSTP_MIN_HELLO_TIME ? 740 cu->cu_hello_time : BSTP_MIN_HELLO_TIME); 741 742 /* set expiry for the new info */ 743 bstp_set_timer_msgage(bp); 744 745 bp->bp_infois = BSTP_INFO_RECEIVED; 746 bstp_assign_roles(bs); 747 break; 748 749 case BSTP_PDU_REPEATED: 750 if (cu->cu_proposal && cu->cu_forwarding == 0) 751 bp->bp_proposed = 1; 752 if (cu->cu_topology_change) 753 bp->bp_rcvdtc = 1; 754 if (cu->cu_topology_change_ack) 755 bp->bp_rcvdtca = 1; 756 757 /* rearm the age timer */ 758 bstp_set_timer_msgage(bp); 759 break; 760 761 case BSTP_PDU_INFERIOR: 762 if (cu->cu_learning) { 763 bp->bp_agreed = 1; 764 bp->bp_proposing = 0; 765 } 766 break; 767 768 case BSTP_PDU_INFERIORALT: 769 /* 770 * only point to point links are allowed fast 771 * transitions to forwarding. 772 */ 773 if (cu->cu_agree && bp->bp_ptp_link) { 774 bp->bp_agreed = 1; 775 bp->bp_proposing = 0; 776 } else 777 bp->bp_agreed = 0; 778 779 if (cu->cu_topology_change) 780 bp->bp_rcvdtc = 1; 781 if (cu->cu_topology_change_ack) 782 bp->bp_rcvdtca = 1; 783 break; 784 785 case BSTP_PDU_OTHER: 786 return; /* do nothing */ 787 } 788 789 /* update the state machines with the new data */ 790 bstp_update_state(bs, bp); 791 } 792 793 int 794 bstp_pdu_rcvtype(struct bstp_port *bp, struct bstp_config_unit *cu) 795 { 796 int type; 797 798 /* default return type */ 799 type = BSTP_PDU_OTHER; 800 801 switch (cu->cu_role) { 802 case BSTP_ROLE_DESIGNATED: 803 if (bstp_info_superior(&bp->bp_port_pv, &cu->cu_pv)) 804 /* bpdu priority is superior */ 805 type = BSTP_PDU_SUPERIOR; 806 else if (bstp_info_cmp(&bp->bp_port_pv, &cu->cu_pv) == 807 INFO_SAME) { 808 if (bp->bp_port_msg_age != cu->cu_message_age || 809 bp->bp_port_max_age != cu->cu_max_age || 810 bp->bp_port_fdelay != cu->cu_forward_delay || 811 bp->bp_port_htime != cu->cu_hello_time) 812 /* bpdu priority is equal and timers differ */ 813 type = BSTP_PDU_SUPERIOR; 814 else 815 /* bpdu is equal */ 816 type = BSTP_PDU_REPEATED; 817 } else 818 /* bpdu priority is worse */ 819 type = BSTP_PDU_INFERIOR; 820 821 break; 822 823 case BSTP_ROLE_ROOT: 824 case BSTP_ROLE_ALTERNATE: 825 case BSTP_ROLE_BACKUP: 826 if (bstp_info_cmp(&bp->bp_port_pv, &cu->cu_pv) <= INFO_SAME) 827 /* 828 * not a designated port and priority is the same or 829 * worse 830 */ 831 type = BSTP_PDU_INFERIORALT; 832 break; 833 } 834 835 return (type); 836 } 837 838 int 839 bstp_pdu_bettersame(struct bstp_port *bp, int newinfo) 840 { 841 if (newinfo == BSTP_INFO_RECEIVED && 842 bp->bp_infois == BSTP_INFO_RECEIVED && 843 bstp_info_cmp(&bp->bp_port_pv, &bp->bp_msg_cu.cu_pv) >= INFO_SAME) 844 return (1); 845 846 if (newinfo == BSTP_INFO_MINE && 847 bp->bp_infois == BSTP_INFO_MINE && 848 bstp_info_cmp(&bp->bp_port_pv, &bp->bp_desg_pv) >= INFO_SAME) 849 return (1); 850 851 return (0); 852 } 853 854 int 855 bstp_info_cmp(struct bstp_pri_vector *pv, 856 struct bstp_pri_vector *cpv) 857 { 858 if (cpv->pv_root_id < pv->pv_root_id) 859 return (INFO_BETTER); 860 if (cpv->pv_root_id > pv->pv_root_id) 861 return (INFO_WORSE); 862 863 if (cpv->pv_cost < pv->pv_cost) 864 return (INFO_BETTER); 865 if (cpv->pv_cost > pv->pv_cost) 866 return (INFO_WORSE); 867 868 if (cpv->pv_dbridge_id < pv->pv_dbridge_id) 869 return (INFO_BETTER); 870 if (cpv->pv_dbridge_id > pv->pv_dbridge_id) 871 return (INFO_WORSE); 872 873 if (cpv->pv_dport_id < pv->pv_dport_id) 874 return (INFO_BETTER); 875 if (cpv->pv_dport_id > pv->pv_dport_id) 876 return (INFO_WORSE); 877 878 return (INFO_SAME); 879 } 880 881 /* 882 * This message priority vector is superior to the port priority vector and 883 * will replace it if, and only if, the message priority vector is better than 884 * the port priority vector, or the message has been transmitted from the same 885 * designated bridge and designated port as the port priority vector. 886 */ 887 int 888 bstp_info_superior(struct bstp_pri_vector *pv, 889 struct bstp_pri_vector *cpv) 890 { 891 if (bstp_info_cmp(pv, cpv) == INFO_BETTER || 892 (bstp_same_bridgeid(pv->pv_dbridge_id, cpv->pv_dbridge_id) && 893 (cpv->pv_dport_id & 0xfff) == (pv->pv_dport_id & 0xfff))) 894 return (1); 895 return (0); 896 } 897 898 void 899 bstp_reset(struct bstp_state *bs) 900 { 901 /* default to our priority vector */ 902 bs->bs_root_pv = bs->bs_bridge_pv; 903 bs->bs_root_msg_age = 0; 904 bs->bs_root_max_age = bs->bs_bridge_max_age; 905 bs->bs_root_fdelay = bs->bs_bridge_fdelay; 906 bs->bs_root_htime = bs->bs_bridge_htime; 907 bs->bs_root_port = NULL; 908 } 909 910 void 911 bstp_assign_roles(struct bstp_state *bs) 912 { 913 struct bstp_port *bp, *rbp = NULL; 914 struct bstp_pri_vector pv; 915 916 bstp_reset(bs); 917 918 /* check if any received info supersedes us */ 919 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) { 920 if (bp->bp_infois != BSTP_INFO_RECEIVED) 921 continue; 922 923 pv = bp->bp_port_pv; 924 pv.pv_cost += bp->bp_path_cost; 925 926 /* 927 * The root priority vector is the best of the set comprising 928 * the bridge priority vector plus all root path priority 929 * vectors whose bridge address is not equal to us. 930 */ 931 if (bstp_same_bridgeid(pv.pv_dbridge_id, 932 bs->bs_bridge_pv.pv_dbridge_id) == 0 && 933 bstp_info_cmp(&bs->bs_root_pv, &pv) == INFO_BETTER) { 934 /* the port vector replaces the root */ 935 bs->bs_root_pv = pv; 936 bs->bs_root_msg_age = bp->bp_port_msg_age + 937 BSTP_MESSAGE_AGE_INCR; 938 bs->bs_root_max_age = bp->bp_port_max_age; 939 bs->bs_root_fdelay = bp->bp_port_fdelay; 940 bs->bs_root_htime = bp->bp_port_htime; 941 rbp = bp; 942 } 943 } 944 945 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) { 946 /* calculate the port designated vector */ 947 bp->bp_desg_pv.pv_root_id = bs->bs_root_pv.pv_root_id; 948 bp->bp_desg_pv.pv_cost = bs->bs_root_pv.pv_cost; 949 bp->bp_desg_pv.pv_dbridge_id = bs->bs_bridge_pv.pv_dbridge_id; 950 bp->bp_desg_pv.pv_dport_id = bp->bp_port_id; 951 bp->bp_desg_pv.pv_port_id = bp->bp_port_id; 952 953 /* calculate designated times */ 954 bp->bp_desg_msg_age = bs->bs_root_msg_age; 955 bp->bp_desg_max_age = bs->bs_root_max_age; 956 bp->bp_desg_fdelay = bs->bs_root_fdelay; 957 bp->bp_desg_htime = bs->bs_bridge_htime; 958 959 960 switch (bp->bp_infois) { 961 case BSTP_INFO_DISABLED: 962 bstp_set_port_role(bp, BSTP_ROLE_DISABLED); 963 break; 964 965 case BSTP_INFO_AGED: 966 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED); 967 bstp_update_info(bp); 968 break; 969 970 case BSTP_INFO_MINE: 971 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED); 972 /* update the port info if stale */ 973 if (bstp_info_cmp(&bp->bp_port_pv, 974 &bp->bp_desg_pv) != INFO_SAME || 975 (rbp != NULL && 976 (bp->bp_port_msg_age != rbp->bp_port_msg_age || 977 bp->bp_port_max_age != rbp->bp_port_max_age || 978 bp->bp_port_fdelay != rbp->bp_port_fdelay || 979 bp->bp_port_htime != rbp->bp_port_htime))) 980 bstp_update_info(bp); 981 break; 982 983 case BSTP_INFO_RECEIVED: 984 if (bp == rbp) { 985 /* 986 * root priority is derived from this 987 * port, make it the root port. 988 */ 989 bstp_set_port_role(bp, BSTP_ROLE_ROOT); 990 bs->bs_root_port = bp; 991 } else if (bstp_info_cmp(&bp->bp_port_pv, 992 &bp->bp_desg_pv) == INFO_BETTER) { 993 /* 994 * the port priority is lower than the root 995 * port. 996 */ 997 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED); 998 bstp_update_info(bp); 999 } else { 1000 if (bstp_same_bridgeid( 1001 bp->bp_port_pv.pv_dbridge_id, 1002 bs->bs_bridge_pv.pv_dbridge_id)) { 1003 /* 1004 * the designated bridge refers to 1005 * another port on this bridge. 1006 */ 1007 bstp_set_port_role(bp, 1008 BSTP_ROLE_BACKUP); 1009 } else { 1010 /* 1011 * the port is an inferior path to the 1012 * root bridge. 1013 */ 1014 bstp_set_port_role(bp, 1015 BSTP_ROLE_ALTERNATE); 1016 } 1017 } 1018 break; 1019 } 1020 } 1021 } 1022 1023 void 1024 bstp_update_state(struct bstp_state *bs, struct bstp_port *bp) 1025 { 1026 struct bstp_port *bp2; 1027 int synced; 1028 1029 /* check if all the ports have synchronized again */ 1030 if (!bs->bs_allsynced) { 1031 synced = 1; 1032 LIST_FOREACH(bp2, &bs->bs_bplist, bp_next) { 1033 if (!(bp2->bp_synced || 1034 bp2->bp_role == BSTP_ROLE_ROOT)) { 1035 synced = 0; 1036 break; 1037 } 1038 } 1039 bs->bs_allsynced = synced; 1040 } 1041 1042 bstp_update_roles(bs, bp); 1043 bstp_update_tc(bp); 1044 } 1045 1046 void 1047 bstp_update_roles(struct bstp_state *bs, struct bstp_port *bp) 1048 { 1049 switch (bp->bp_role) { 1050 case BSTP_ROLE_DISABLED: 1051 /* Clear any flags if set */ 1052 if (bp->bp_sync || !bp->bp_synced || bp->bp_reroot) { 1053 bp->bp_sync = 0; 1054 bp->bp_synced = 1; 1055 bp->bp_reroot = 0; 1056 } 1057 break; 1058 1059 case BSTP_ROLE_ALTERNATE: 1060 case BSTP_ROLE_BACKUP: 1061 if ((bs->bs_allsynced && !bp->bp_agree) || 1062 (bp->bp_proposed && bp->bp_agree)) { 1063 bp->bp_proposed = 0; 1064 bp->bp_agree = 1; 1065 bp->bp_flags |= BSTP_PORT_NEWINFO; 1066 DPRINTF(bp, "-> ALTERNATE_AGREED\n"); 1067 } 1068 1069 if (bp->bp_proposed && !bp->bp_agree) { 1070 bstp_set_all_sync(bs); 1071 bp->bp_proposed = 0; 1072 DPRINTF(bp, "-> ALTERNATE_PROPOSED\n"); 1073 } 1074 1075 /* Clear any flags if set */ 1076 if (bp->bp_sync || !bp->bp_synced || bp->bp_reroot) { 1077 bp->bp_sync = 0; 1078 bp->bp_synced = 1; 1079 bp->bp_reroot = 0; 1080 DPRINTF(bp, "-> ALTERNATE_PORT\n"); 1081 } 1082 break; 1083 1084 case BSTP_ROLE_ROOT: 1085 if (bp->bp_state != BSTP_IFSTATE_FORWARDING && !bp->bp_reroot) { 1086 bstp_set_all_reroot(bs); 1087 DPRINTF(bp, "-> ROOT_REROOT\n"); 1088 } 1089 1090 if ((bs->bs_allsynced && !bp->bp_agree) || 1091 (bp->bp_proposed && bp->bp_agree)) { 1092 bp->bp_proposed = 0; 1093 bp->bp_sync = 0; 1094 bp->bp_agree = 1; 1095 bp->bp_flags |= BSTP_PORT_NEWINFO; 1096 DPRINTF(bp, "-> ROOT_AGREED\n"); 1097 } 1098 1099 if (bp->bp_proposed && !bp->bp_agree) { 1100 bstp_set_all_sync(bs); 1101 bp->bp_proposed = 0; 1102 DPRINTF(bp, "-> ROOT_PROPOSED\n"); 1103 } 1104 1105 if (bp->bp_state != BSTP_IFSTATE_FORWARDING && 1106 (bp->bp_forward_delay_timer.active == 0 || 1107 (bstp_rerooted(bs, bp) && 1108 bp->bp_recent_backup_timer.active == 0 && 1109 bp->bp_protover == BSTP_PROTO_RSTP))) { 1110 switch (bp->bp_state) { 1111 case BSTP_IFSTATE_DISCARDING: 1112 bstp_set_port_state(bp, BSTP_IFSTATE_LEARNING); 1113 break; 1114 case BSTP_IFSTATE_LEARNING: 1115 bstp_set_port_state(bp, 1116 BSTP_IFSTATE_FORWARDING); 1117 break; 1118 } 1119 } 1120 1121 if (bp->bp_state == BSTP_IFSTATE_FORWARDING && bp->bp_reroot) { 1122 bp->bp_reroot = 0; 1123 DPRINTF(bp, "-> ROOT_REROOTED\n"); 1124 } 1125 break; 1126 1127 case BSTP_ROLE_DESIGNATED: 1128 if (bp->bp_recent_root_timer.active == 0 && bp->bp_reroot) { 1129 bp->bp_reroot = 0; 1130 DPRINTF(bp, "-> DESIGNATED_RETIRED\n"); 1131 } 1132 1133 if ((bp->bp_state == BSTP_IFSTATE_DISCARDING && 1134 !bp->bp_synced) || (bp->bp_agreed && !bp->bp_synced) || 1135 (bp->bp_operedge && !bp->bp_synced) || 1136 (bp->bp_sync && bp->bp_synced)) { 1137 bstp_timer_stop(&bp->bp_recent_root_timer); 1138 bp->bp_synced = 1; 1139 bp->bp_sync = 0; 1140 DPRINTF(bp, "-> DESIGNATED_SYNCED\n"); 1141 } 1142 1143 if (bp->bp_state != BSTP_IFSTATE_FORWARDING && 1144 !bp->bp_agreed && !bp->bp_proposing && 1145 !bp->bp_operedge) { 1146 bp->bp_proposing = 1; 1147 bp->bp_flags |= BSTP_PORT_NEWINFO; 1148 bstp_timer_start(&bp->bp_edge_delay_timer, 1149 (bp->bp_ptp_link ? BSTP_DEFAULT_MIGRATE_DELAY : 1150 bp->bp_desg_max_age)); 1151 DPRINTF(bp, "-> DESIGNATED_PROPOSE\n"); 1152 } 1153 1154 if (bp->bp_state != BSTP_IFSTATE_FORWARDING && 1155 (bp->bp_forward_delay_timer.active == 0 || bp->bp_agreed || 1156 bp->bp_operedge) && 1157 (bp->bp_recent_root_timer.active == 0 || !bp->bp_reroot) && 1158 !bp->bp_sync) { 1159 if (bp->bp_agreed) 1160 DPRINTF(bp, "-> AGREED\n"); 1161 /* 1162 * If agreed|operedge then go straight to forwarding, 1163 * otherwise follow discard -> learn -> forward. 1164 */ 1165 if (bp->bp_agreed || bp->bp_operedge || 1166 bp->bp_state == BSTP_IFSTATE_LEARNING) { 1167 bstp_set_port_state(bp, 1168 BSTP_IFSTATE_FORWARDING); 1169 bp->bp_agreed = bp->bp_protover; 1170 } else if (bp->bp_state == BSTP_IFSTATE_DISCARDING) 1171 bstp_set_port_state(bp, BSTP_IFSTATE_LEARNING); 1172 } 1173 1174 if (((bp->bp_sync && !bp->bp_synced) || 1175 (bp->bp_reroot && bp->bp_recent_root_timer.active) || 1176 (bp->bp_flags & BSTP_PORT_DISPUTED)) && !bp->bp_operedge && 1177 bp->bp_state != BSTP_IFSTATE_DISCARDING) { 1178 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING); 1179 bp->bp_flags &= ~BSTP_PORT_DISPUTED; 1180 bstp_timer_start(&bp->bp_forward_delay_timer, 1181 bp->bp_protover == BSTP_PROTO_RSTP ? 1182 bp->bp_desg_htime : bp->bp_desg_fdelay); 1183 DPRINTF(bp, "-> DESIGNATED_DISCARD\n"); 1184 } 1185 break; 1186 } 1187 1188 if (bp->bp_flags & BSTP_PORT_NEWINFO) 1189 bstp_transmit(bs, bp); 1190 } 1191 1192 void 1193 bstp_update_tc(struct bstp_port *bp) 1194 { 1195 switch (bp->bp_tcstate) { 1196 case BSTP_TCSTATE_ACTIVE: 1197 if ((bp->bp_role != BSTP_ROLE_DESIGNATED && 1198 bp->bp_role != BSTP_ROLE_ROOT) || bp->bp_operedge) 1199 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING); 1200 1201 if (bp->bp_rcvdtcn) 1202 bstp_set_port_tc(bp, BSTP_TCSTATE_TCN); 1203 if (bp->bp_rcvdtc) 1204 bstp_set_port_tc(bp, BSTP_TCSTATE_TC); 1205 1206 if (bp->bp_tc_prop && !bp->bp_operedge) 1207 bstp_set_port_tc(bp, BSTP_TCSTATE_PROPAG); 1208 1209 if (bp->bp_rcvdtca) 1210 bstp_set_port_tc(bp, BSTP_TCSTATE_ACK); 1211 break; 1212 1213 case BSTP_TCSTATE_INACTIVE: 1214 if ((bp->bp_state == BSTP_IFSTATE_LEARNING || 1215 bp->bp_state == BSTP_IFSTATE_FORWARDING) && 1216 bp->bp_fdbflush == 0) 1217 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING); 1218 break; 1219 1220 case BSTP_TCSTATE_LEARNING: 1221 if (bp->bp_rcvdtc || bp->bp_rcvdtcn || bp->bp_rcvdtca || 1222 bp->bp_tc_prop) 1223 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING); 1224 else if (bp->bp_role != BSTP_ROLE_DESIGNATED && 1225 bp->bp_role != BSTP_ROLE_ROOT && 1226 bp->bp_state == BSTP_IFSTATE_DISCARDING) 1227 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE); 1228 1229 if ((bp->bp_role == BSTP_ROLE_DESIGNATED || 1230 bp->bp_role == BSTP_ROLE_ROOT) && 1231 bp->bp_state == BSTP_IFSTATE_FORWARDING && 1232 !bp->bp_operedge) 1233 bstp_set_port_tc(bp, BSTP_TCSTATE_DETECTED); 1234 break; 1235 1236 /* these are transient states and go straight back to ACTIVE */ 1237 case BSTP_TCSTATE_DETECTED: 1238 case BSTP_TCSTATE_TCN: 1239 case BSTP_TCSTATE_TC: 1240 case BSTP_TCSTATE_PROPAG: 1241 case BSTP_TCSTATE_ACK: 1242 DPRINTF(bp, "Invalid TC state\n"); 1243 break; 1244 } 1245 1246 } 1247 1248 void 1249 bstp_update_info(struct bstp_port *bp) 1250 { 1251 struct bstp_state *bs = bp->bp_bs; 1252 1253 bp->bp_proposing = 0; 1254 bp->bp_proposed = 0; 1255 1256 if (bp->bp_agreed && !bstp_pdu_bettersame(bp, BSTP_INFO_MINE)) 1257 bp->bp_agreed = 0; 1258 1259 if (bp->bp_synced && !bp->bp_agreed) { 1260 bp->bp_synced = 0; 1261 bs->bs_allsynced = 0; 1262 } 1263 1264 /* copy the designated pv to the port */ 1265 bp->bp_port_pv = bp->bp_desg_pv; 1266 bp->bp_port_msg_age = bp->bp_desg_msg_age; 1267 bp->bp_port_max_age = bp->bp_desg_max_age; 1268 bp->bp_port_fdelay = bp->bp_desg_fdelay; 1269 bp->bp_port_htime = bp->bp_desg_htime; 1270 bp->bp_infois = BSTP_INFO_MINE; 1271 1272 /* Set transmit flag but do not immediately send */ 1273 bp->bp_flags |= BSTP_PORT_NEWINFO; 1274 } 1275 1276 /* set tcprop on every port other than the caller */ 1277 void 1278 bstp_set_other_tcprop(struct bstp_port *bp) 1279 { 1280 struct bstp_state *bs = bp->bp_bs; 1281 struct bstp_port *bp2; 1282 1283 LIST_FOREACH(bp2, &bs->bs_bplist, bp_next) { 1284 if (bp2 == bp) 1285 continue; 1286 bp2->bp_tc_prop = 1; 1287 } 1288 } 1289 1290 void 1291 bstp_set_all_reroot(struct bstp_state *bs) 1292 { 1293 struct bstp_port *bp; 1294 1295 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) 1296 bp->bp_reroot = 1; 1297 } 1298 1299 void 1300 bstp_set_all_sync(struct bstp_state *bs) 1301 { 1302 struct bstp_port *bp; 1303 1304 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) { 1305 bp->bp_sync = 1; 1306 bp->bp_synced = 0; /* Not explicit in spec */ 1307 } 1308 1309 bs->bs_allsynced = 0; 1310 } 1311 1312 void 1313 bstp_set_port_state(struct bstp_port *bp, int state) 1314 { 1315 if (bp->bp_state == state) 1316 return; 1317 1318 bp->bp_state = state; 1319 1320 switch (bp->bp_state) { 1321 case BSTP_IFSTATE_DISCARDING: 1322 DPRINTF(bp, "state changed to DISCARDING\n"); 1323 break; 1324 1325 case BSTP_IFSTATE_LEARNING: 1326 DPRINTF(bp, "state changed to LEARNING\n"); 1327 bstp_timer_start(&bp->bp_forward_delay_timer, 1328 bp->bp_protover == BSTP_PROTO_RSTP ? 1329 bp->bp_desg_htime : bp->bp_desg_fdelay); 1330 break; 1331 1332 case BSTP_IFSTATE_FORWARDING: 1333 DPRINTF(bp, "state changed to FORWARDING\n"); 1334 bstp_timer_stop(&bp->bp_forward_delay_timer); 1335 /* Record that we enabled forwarding */ 1336 bp->bp_forward_transitions++; 1337 break; 1338 } 1339 } 1340 1341 void 1342 bstp_set_port_role(struct bstp_port *bp, int role) 1343 { 1344 struct bstp_state *bs = bp->bp_bs; 1345 1346 if (bp->bp_role == role) 1347 return; 1348 1349 /* perform pre-change tasks */ 1350 switch (bp->bp_role) { 1351 case BSTP_ROLE_DISABLED: 1352 bstp_timer_start(&bp->bp_forward_delay_timer, 1353 bp->bp_desg_max_age); 1354 break; 1355 1356 case BSTP_ROLE_BACKUP: 1357 bstp_timer_start(&bp->bp_recent_backup_timer, 1358 bp->bp_desg_htime * 2); 1359 /* FALLTHROUGH */ 1360 case BSTP_ROLE_ALTERNATE: 1361 bstp_timer_start(&bp->bp_forward_delay_timer, 1362 bp->bp_desg_fdelay); 1363 bp->bp_sync = 0; 1364 bp->bp_synced = 1; 1365 bp->bp_reroot = 0; 1366 break; 1367 1368 case BSTP_ROLE_ROOT: 1369 bstp_timer_start(&bp->bp_recent_root_timer, 1370 BSTP_DEFAULT_FORWARD_DELAY); 1371 break; 1372 } 1373 1374 bp->bp_role = role; 1375 /* clear values not carried between roles */ 1376 bp->bp_proposing = 0; 1377 bs->bs_allsynced = 0; 1378 1379 /* initialise the new role */ 1380 switch (bp->bp_role) { 1381 case BSTP_ROLE_DISABLED: 1382 case BSTP_ROLE_ALTERNATE: 1383 case BSTP_ROLE_BACKUP: 1384 DPRINTF(bp, "role -> ALT/BACK/DISABLED\n"); 1385 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING); 1386 bstp_timer_stop(&bp->bp_recent_root_timer); 1387 bstp_timer_latch(&bp->bp_forward_delay_timer); 1388 bp->bp_sync = 0; 1389 bp->bp_synced = 1; 1390 bp->bp_reroot = 0; 1391 break; 1392 1393 case BSTP_ROLE_ROOT: 1394 DPRINTF(bp, "role -> ROOT\n"); 1395 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING); 1396 bstp_timer_latch(&bp->bp_recent_root_timer); 1397 bp->bp_proposing = 0; 1398 break; 1399 1400 case BSTP_ROLE_DESIGNATED: 1401 DPRINTF(bp, "role -> DESIGNATED\n"); 1402 bstp_timer_start(&bp->bp_hello_timer, 1403 bp->bp_desg_htime); 1404 bp->bp_agree = 0; 1405 break; 1406 } 1407 1408 /* let the TC state know that the role changed */ 1409 bstp_update_tc(bp); 1410 } 1411 1412 void 1413 bstp_set_port_proto(struct bstp_port *bp, int proto) 1414 { 1415 struct bstp_state *bs = bp->bp_bs; 1416 1417 /* supported protocol versions */ 1418 switch (proto) { 1419 case BSTP_PROTO_STP: 1420 /* we can downgrade protocols only */ 1421 bstp_timer_stop(&bp->bp_migrate_delay_timer); 1422 /* clear unsupported features */ 1423 bp->bp_operedge = 0; 1424 break; 1425 1426 case BSTP_PROTO_RSTP: 1427 bstp_timer_start(&bp->bp_migrate_delay_timer, 1428 bs->bs_migration_delay); 1429 break; 1430 1431 default: 1432 DPRINTF(bp, "Unsupported STP version %d\n", proto); 1433 return; 1434 } 1435 1436 bp->bp_protover = proto; 1437 bp->bp_flags &= ~BSTP_PORT_CANMIGRATE; 1438 } 1439 1440 void 1441 bstp_set_port_tc(struct bstp_port *bp, int state) 1442 { 1443 struct bstp_state *bs = bp->bp_bs; 1444 1445 bp->bp_tcstate = state; 1446 1447 /* initialise the new state */ 1448 switch (bp->bp_tcstate) { 1449 case BSTP_TCSTATE_ACTIVE: 1450 DPRINTF(bp, "-> TC_ACTIVE\n"); 1451 /* nothing to do */ 1452 break; 1453 1454 case BSTP_TCSTATE_INACTIVE: 1455 bstp_timer_stop(&bp->bp_tc_timer); 1456 /* flush routes on the parent bridge */ 1457 bp->bp_fdbflush = 1; 1458 bstp_notify_rtage(bp, 0); 1459 bp->bp_tc_ack = 0; 1460 DPRINTF(bp, "-> TC_INACTIVE\n"); 1461 break; 1462 1463 case BSTP_TCSTATE_LEARNING: 1464 bp->bp_rcvdtc = 0; 1465 bp->bp_rcvdtcn = 0; 1466 bp->bp_rcvdtca = 0; 1467 bp->bp_tc_prop = 0; 1468 DPRINTF(bp, "-> TC_LEARNING\n"); 1469 break; 1470 1471 case BSTP_TCSTATE_DETECTED: 1472 bstp_set_timer_tc(bp); 1473 bstp_set_other_tcprop(bp); 1474 /* send out notification */ 1475 bp->bp_flags |= BSTP_PORT_NEWINFO; 1476 bstp_transmit(bs, bp); 1477 getmicrotime(&bs->bs_last_tc_time); 1478 DPRINTF(bp, "-> TC_DETECTED\n"); 1479 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */ 1480 break; 1481 1482 case BSTP_TCSTATE_TCN: 1483 bstp_set_timer_tc(bp); 1484 DPRINTF(bp, "-> TC_TCN\n"); 1485 /* FALLTHROUGH */ 1486 case BSTP_TCSTATE_TC: 1487 bp->bp_rcvdtc = 0; 1488 bp->bp_rcvdtcn = 0; 1489 if (bp->bp_role == BSTP_ROLE_DESIGNATED) 1490 bp->bp_tc_ack = 1; 1491 1492 bstp_set_other_tcprop(bp); 1493 DPRINTF(bp, "-> TC_TC\n"); 1494 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */ 1495 break; 1496 1497 case BSTP_TCSTATE_PROPAG: 1498 /* flush routes on the parent bridge */ 1499 bp->bp_fdbflush = 1; 1500 bstp_notify_rtage(bp, 0); 1501 bp->bp_tc_prop = 0; 1502 bstp_set_timer_tc(bp); 1503 DPRINTF(bp, "-> TC_PROPAG\n"); 1504 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */ 1505 break; 1506 1507 case BSTP_TCSTATE_ACK: 1508 bstp_timer_stop(&bp->bp_tc_timer); 1509 bp->bp_rcvdtca = 0; 1510 DPRINTF(bp, "-> TC_ACK\n"); 1511 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */ 1512 break; 1513 } 1514 } 1515 1516 void 1517 bstp_set_timer_tc(struct bstp_port *bp) 1518 { 1519 struct bstp_state *bs = bp->bp_bs; 1520 1521 if (bp->bp_tc_timer.active) 1522 return; 1523 1524 switch (bp->bp_protover) { 1525 case BSTP_PROTO_RSTP: 1526 bstp_timer_start(&bp->bp_tc_timer, 1527 bp->bp_desg_htime + BSTP_TICK_VAL); 1528 bp->bp_flags |= BSTP_PORT_NEWINFO; 1529 break; 1530 case BSTP_PROTO_STP: 1531 bstp_timer_start(&bp->bp_tc_timer, 1532 bs->bs_root_max_age + bs->bs_root_fdelay); 1533 break; 1534 } 1535 } 1536 1537 void 1538 bstp_set_timer_msgage(struct bstp_port *bp) 1539 { 1540 if (bp->bp_port_msg_age + BSTP_MESSAGE_AGE_INCR <= 1541 bp->bp_port_max_age) { 1542 bstp_timer_start(&bp->bp_message_age_timer, 1543 bp->bp_port_htime * 3); 1544 } else 1545 /* expires immediately */ 1546 bstp_timer_start(&bp->bp_message_age_timer, 0); 1547 } 1548 1549 int 1550 bstp_rerooted(struct bstp_state *bs, struct bstp_port *bp) 1551 { 1552 struct bstp_port *bp2; 1553 int rr_set = 0; 1554 1555 LIST_FOREACH(bp2, &bs->bs_bplist, bp_next) { 1556 if (bp2 == bp) 1557 continue; 1558 if (bp2->bp_recent_root_timer.active) { 1559 rr_set = 1; 1560 break; 1561 } 1562 } 1563 return (!rr_set); 1564 } 1565 1566 /* 1567 * Calculate the path cost according to the link speed. 1568 */ 1569 u_int32_t 1570 bstp_calc_path_cost(struct bstp_port *bp) 1571 { 1572 struct ifnet *ifp; 1573 u_int32_t path_cost; 1574 1575 /* If the priority has been manually set then retain the value */ 1576 if (bp->bp_flags & BSTP_PORT_ADMCOST) 1577 return bp->bp_path_cost; 1578 1579 if ((ifp = if_get(bp->bp_ifindex)) == NULL) { 1580 return bp->bp_path_cost; 1581 } 1582 1583 if (ifp->if_baudrate < 1000) { 1584 if_put(ifp); 1585 return (BSTP_DEFAULT_PATH_COST); 1586 } 1587 1588 /* formula from section 17.14, IEEE Std 802.1D-2004 */ 1589 path_cost = 20000000000ULL / (ifp->if_baudrate / 1000); 1590 if_put(ifp); 1591 1592 if (path_cost > BSTP_MAX_PATH_COST) 1593 path_cost = BSTP_MAX_PATH_COST; 1594 1595 /* STP compat mode only uses 16 bits of the 32 */ 1596 if (bp->bp_protover == BSTP_PROTO_STP && path_cost > 65535) 1597 path_cost = 65535; 1598 1599 return (path_cost); 1600 } 1601 1602 void 1603 bstp_notify_rtage(struct bstp_port *bp, int pending) 1604 { 1605 int age = 0; 1606 1607 KERNEL_ASSERT_LOCKED(); 1608 1609 switch (bp->bp_protover) { 1610 case BSTP_PROTO_STP: 1611 /* convert to seconds */ 1612 age = bp->bp_desg_fdelay / BSTP_TICK_VAL; 1613 break; 1614 case BSTP_PROTO_RSTP: 1615 age = 0; 1616 break; 1617 } 1618 1619 if (bp->bp_active == 1) { 1620 struct ifnet *ifp; 1621 1622 if ((ifp = if_get(bp->bp_ifindex)) != NULL) 1623 bridge_rtagenode(ifp, age); 1624 if_put(ifp); 1625 } 1626 1627 /* flush is complete */ 1628 bp->bp_fdbflush = 0; 1629 } 1630 1631 void 1632 bstp_ifstate(void *arg) 1633 { 1634 struct ifnet *ifp = (struct ifnet *)arg; 1635 struct bridge_iflist *bif; 1636 struct bstp_port *bp; 1637 struct bstp_state *bs; 1638 int s; 1639 1640 if (ifp->if_type == IFT_BRIDGE) 1641 return; 1642 1643 s = splnet(); 1644 if ((bif = bridge_getbif(ifp)) == NULL) 1645 goto done; 1646 if ((bif->bif_flags & IFBIF_STP) == 0) 1647 goto done; 1648 if ((bp = bif->bif_stp) == NULL) 1649 goto done; 1650 if ((bs = bp->bp_bs) == NULL) 1651 goto done; 1652 1653 /* update the link state */ 1654 bstp_ifupdstatus(bs, bp); 1655 bstp_update_state(bs, bp); 1656 done: 1657 splx(s); 1658 } 1659 1660 void 1661 bstp_ifupdstatus(struct bstp_state *bs, struct bstp_port *bp) 1662 { 1663 struct ifnet *ifp; 1664 1665 if ((ifp = if_get(bp->bp_ifindex)) == NULL) 1666 return; 1667 1668 bp->bp_path_cost = bstp_calc_path_cost(bp); 1669 1670 if ((ifp->if_flags & IFF_UP) && 1671 ifp->if_link_state != LINK_STATE_DOWN) { 1672 if (bp->bp_flags & BSTP_PORT_AUTOPTP) { 1673 /* A full-duplex link is assumed to be ptp */ 1674 bp->bp_ptp_link = ifp->if_link_state == 1675 LINK_STATE_FULL_DUPLEX ? 1 : 0; 1676 } 1677 1678 if (bp->bp_infois == BSTP_INFO_DISABLED) 1679 bstp_enable_port(bs, bp); 1680 } else { 1681 if (bp->bp_infois != BSTP_INFO_DISABLED) 1682 bstp_disable_port(bs, bp); 1683 } 1684 1685 if_put(ifp); 1686 } 1687 1688 void 1689 bstp_enable_port(struct bstp_state *bs, struct bstp_port *bp) 1690 { 1691 bp->bp_infois = BSTP_INFO_AGED; 1692 bstp_assign_roles(bs); 1693 } 1694 1695 void 1696 bstp_disable_port(struct bstp_state *bs, struct bstp_port *bp) 1697 { 1698 bp->bp_infois = BSTP_INFO_DISABLED; 1699 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING); 1700 bstp_assign_roles(bs); 1701 } 1702 1703 void 1704 bstp_tick(void *arg) 1705 { 1706 struct bstp_state *bs = (struct bstp_state *)arg; 1707 struct ifnet *ifp; 1708 struct bstp_port *bp; 1709 int s; 1710 1711 if ((ifp = if_get(bs->bs_ifindex)) == NULL) 1712 return; 1713 1714 s = splnet(); 1715 if ((ifp->if_flags & IFF_RUNNING) == 0) { 1716 splx(s); 1717 if_put(ifp); 1718 return; 1719 } 1720 1721 /* slow timer to catch missed link events */ 1722 if (bstp_timer_expired(&bs->bs_link_timer)) { 1723 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) 1724 bstp_ifupdstatus(bs, bp); 1725 bstp_timer_start(&bs->bs_link_timer, BSTP_LINK_TIMER); 1726 } 1727 1728 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) { 1729 /* no events need to happen for these */ 1730 bstp_timer_expired(&bp->bp_tc_timer); 1731 bstp_timer_expired(&bp->bp_recent_root_timer); 1732 bstp_timer_expired(&bp->bp_forward_delay_timer); 1733 bstp_timer_expired(&bp->bp_recent_backup_timer); 1734 1735 if (bstp_timer_expired(&bp->bp_hello_timer)) 1736 bstp_hello_timer_expiry(bs, bp); 1737 1738 if (bstp_timer_expired(&bp->bp_message_age_timer)) 1739 bstp_message_age_expiry(bs, bp); 1740 1741 if (bstp_timer_expired(&bp->bp_migrate_delay_timer)) 1742 bstp_migrate_delay_expiry(bs, bp); 1743 1744 if (bstp_timer_expired(&bp->bp_edge_delay_timer)) 1745 bstp_edge_delay_expiry(bs, bp); 1746 1747 /* update the various state machines for the port */ 1748 bstp_update_state(bs, bp); 1749 1750 if (bp->bp_txcount > 0) 1751 bp->bp_txcount--; 1752 } 1753 1754 if (ifp->if_flags & IFF_RUNNING) 1755 timeout_add_sec(&bs->bs_bstptimeout, 1); 1756 1757 splx(s); 1758 if_put(ifp); 1759 } 1760 1761 void 1762 bstp_timer_start(struct bstp_timer *t, u_int16_t v) 1763 { 1764 t->value = v; 1765 t->active = 1; 1766 t->latched = 0; 1767 } 1768 1769 void 1770 bstp_timer_stop(struct bstp_timer *t) 1771 { 1772 t->value = 0; 1773 t->active = 0; 1774 t->latched = 0; 1775 } 1776 1777 void 1778 bstp_timer_latch(struct bstp_timer *t) 1779 { 1780 t->latched = 1; 1781 t->active = 1; 1782 } 1783 1784 int 1785 bstp_timer_expired(struct bstp_timer *t) 1786 { 1787 if (t->active == 0 || t->latched) 1788 return (0); 1789 t->value -= BSTP_TICK_VAL; 1790 if (t->value <= 0) { 1791 bstp_timer_stop(t); 1792 return (1); 1793 } 1794 return (0); 1795 } 1796 1797 void 1798 bstp_hello_timer_expiry(struct bstp_state *bs, struct bstp_port *bp) 1799 { 1800 if ((bp->bp_flags & BSTP_PORT_NEWINFO) || 1801 bp->bp_role == BSTP_ROLE_DESIGNATED || 1802 (bp->bp_role == BSTP_ROLE_ROOT && 1803 bp->bp_tc_timer.active == 1)) { 1804 bstp_timer_start(&bp->bp_hello_timer, bp->bp_desg_htime); 1805 bp->bp_flags |= BSTP_PORT_NEWINFO; 1806 bstp_transmit(bs, bp); 1807 } 1808 } 1809 1810 void 1811 bstp_message_age_expiry(struct bstp_state *bs, struct bstp_port *bp) 1812 { 1813 if (bp->bp_infois == BSTP_INFO_RECEIVED) { 1814 bp->bp_infois = BSTP_INFO_AGED; 1815 bstp_assign_roles(bs); 1816 DPRINTF(bp, "aged info\n"); 1817 } 1818 } 1819 1820 void 1821 bstp_migrate_delay_expiry(struct bstp_state *bs, struct bstp_port *bp) 1822 { 1823 bp->bp_flags |= BSTP_PORT_CANMIGRATE; 1824 } 1825 1826 void 1827 bstp_edge_delay_expiry(struct bstp_state *bs, struct bstp_port *bp) 1828 { 1829 if ((bp->bp_flags & BSTP_PORT_AUTOEDGE) && 1830 bp->bp_protover == BSTP_PROTO_RSTP && bp->bp_proposing && 1831 bp->bp_role == BSTP_ROLE_DESIGNATED) 1832 bp->bp_operedge = 1; 1833 } 1834 1835 int 1836 bstp_addr_cmp(const u_int8_t *a, const u_int8_t *b) 1837 { 1838 int i, d; 1839 1840 for (i = 0, d = 0; i < ETHER_ADDR_LEN && d == 0; i++) { 1841 d = ((int)a[i]) - ((int)b[i]); 1842 } 1843 1844 return (d); 1845 } 1846 1847 /* 1848 * compare the bridge address component of the bridgeid 1849 */ 1850 int 1851 bstp_same_bridgeid(u_int64_t id1, u_int64_t id2) 1852 { 1853 u_char addr1[ETHER_ADDR_LEN]; 1854 u_char addr2[ETHER_ADDR_LEN]; 1855 1856 PV2ADDR(id1, addr1); 1857 PV2ADDR(id2, addr2); 1858 1859 if (bstp_addr_cmp(addr1, addr2) == 0) 1860 return (1); 1861 1862 return (0); 1863 } 1864 1865 void 1866 bstp_initialization(struct bstp_state *bs) 1867 { 1868 struct bstp_port *bp; 1869 struct ifnet *mif = NULL; 1870 u_char *e_addr; 1871 1872 /* 1873 * Search through the Ethernet interfaces and find the one 1874 * with the lowest value. 1875 * Make sure we take the address from an interface that is 1876 * part of the bridge to make sure two bridges on the system 1877 * will not use the same one. It is not possible for mif to be 1878 * null, at this point we have at least one STP port and hence 1879 * at least one NIC. 1880 */ 1881 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) { 1882 struct ifnet *ifp; 1883 1884 if (mif == NULL) { 1885 mif = if_get(bp->bp_ifindex); 1886 continue; 1887 } 1888 1889 if ((ifp = if_get(bp->bp_ifindex)) == NULL) 1890 continue; 1891 1892 if (bstp_addr_cmp(LLADDR(ifp->if_sadl), 1893 LLADDR(mif->if_sadl)) < 0) { 1894 if_put(mif); 1895 mif = ifp; 1896 continue; 1897 } 1898 if_put(ifp); 1899 } 1900 1901 if (mif == NULL) { 1902 bstp_stop(bs); 1903 bstp_reset(bs); 1904 return; 1905 } 1906 1907 e_addr = LLADDR(mif->if_sadl); 1908 if_put(mif); 1909 bs->bs_bridge_pv.pv_dbridge_id = 1910 (((u_int64_t)bs->bs_bridge_priority) << 48) | 1911 (((u_int64_t)e_addr[0]) << 40) | 1912 (((u_int64_t)e_addr[1]) << 32) | 1913 (((u_int64_t)e_addr[2]) << 24) | 1914 (((u_int64_t)e_addr[3]) << 16) | 1915 (((u_int64_t)e_addr[4]) << 8) | 1916 (((u_int64_t)e_addr[5])); 1917 1918 bs->bs_bridge_pv.pv_root_id = bs->bs_bridge_pv.pv_dbridge_id; 1919 bs->bs_bridge_pv.pv_cost = 0; 1920 bs->bs_bridge_pv.pv_dport_id = 0; 1921 bs->bs_bridge_pv.pv_port_id = 0; 1922 1923 if (!timeout_initialized(&bs->bs_bstptimeout)) 1924 timeout_set(&bs->bs_bstptimeout, bstp_tick, bs); 1925 if (!timeout_pending(&bs->bs_bstptimeout)) 1926 timeout_add_sec(&bs->bs_bstptimeout, 1); 1927 1928 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) { 1929 bp->bp_port_id = (bp->bp_priority << 8) | 1930 (bp->bp_ifindex & 0xfff); 1931 bstp_ifupdstatus(bs, bp); 1932 } 1933 1934 bstp_assign_roles(bs); 1935 bstp_timer_start(&bs->bs_link_timer, BSTP_LINK_TIMER); 1936 } 1937 1938 struct bstp_state * 1939 bstp_create(void) 1940 { 1941 struct bstp_state *bs; 1942 1943 bs = malloc(sizeof(*bs), M_DEVBUF, M_WAITOK|M_ZERO); 1944 LIST_INIT(&bs->bs_bplist); 1945 1946 bs->bs_bridge_max_age = BSTP_DEFAULT_MAX_AGE; 1947 bs->bs_bridge_htime = BSTP_DEFAULT_HELLO_TIME; 1948 bs->bs_bridge_fdelay = BSTP_DEFAULT_FORWARD_DELAY; 1949 bs->bs_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY; 1950 bs->bs_hold_time = BSTP_DEFAULT_HOLD_TIME; 1951 bs->bs_migration_delay = BSTP_DEFAULT_MIGRATE_DELAY; 1952 bs->bs_txholdcount = BSTP_DEFAULT_HOLD_COUNT; 1953 bs->bs_protover = BSTP_PROTO_RSTP; /* STP instead of RSTP? */ 1954 1955 getmicrotime(&bs->bs_last_tc_time); 1956 1957 return (bs); 1958 } 1959 1960 void 1961 bstp_destroy(struct bstp_state *bs) 1962 { 1963 if (bs == NULL) 1964 return; 1965 1966 if (!LIST_EMPTY(&bs->bs_bplist)) 1967 panic("bstp still active"); 1968 1969 free(bs, M_DEVBUF, sizeof *bs); 1970 } 1971 1972 void 1973 bstp_enable(struct bstp_state *bs, unsigned int ifindex) 1974 { 1975 bs->bs_ifindex = ifindex; 1976 bstp_initialization(bs); 1977 } 1978 1979 void 1980 bstp_disable(struct bstp_state *bs) 1981 { 1982 if (timeout_initialized(&bs->bs_bstptimeout)) 1983 timeout_del(&bs->bs_bstptimeout); 1984 bs->bs_ifindex = 0; 1985 } 1986 1987 void 1988 bstp_stop(struct bstp_state *bs) 1989 { 1990 struct bstp_port *bp; 1991 1992 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) 1993 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING); 1994 1995 if (timeout_initialized(&bs->bs_bstptimeout)) 1996 timeout_del(&bs->bs_bstptimeout); 1997 } 1998 1999 struct bstp_port * 2000 bstp_add(struct bstp_state *bs, struct ifnet *ifp) 2001 { 2002 struct bstp_port *bp; 2003 2004 switch (ifp->if_type) { 2005 case IFT_ETHER: /* These can do spanning tree. */ 2006 break; 2007 default: 2008 /* Nothing else can. */ 2009 return (NULL); 2010 } 2011 2012 bp = malloc(sizeof(*bp), M_DEVBUF, M_NOWAIT|M_ZERO); 2013 if (bp == NULL) 2014 return (NULL); 2015 2016 bp->bp_ifindex = ifp->if_index; 2017 bp->bp_bs = bs; 2018 bp->bp_priority = BSTP_DEFAULT_PORT_PRIORITY; 2019 bp->bp_txcount = 0; 2020 2021 /* Init state */ 2022 bp->bp_infois = BSTP_INFO_DISABLED; 2023 bp->bp_flags = BSTP_PORT_AUTOEDGE | BSTP_PORT_AUTOPTP; 2024 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING); 2025 bstp_set_port_proto(bp, bs->bs_protover); 2026 bstp_set_port_role(bp, BSTP_ROLE_DISABLED); 2027 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE); 2028 bp->bp_path_cost = bstp_calc_path_cost(bp); 2029 2030 LIST_INSERT_HEAD(&bs->bs_bplist, bp, bp_next); 2031 2032 bp->bp_active = 1; 2033 bp->bp_flags |= BSTP_PORT_NEWINFO; 2034 bstp_initialization(bs); 2035 bstp_update_roles(bs, bp); 2036 2037 /* Register callback for physical link state changes */ 2038 task_set(&bp->bp_ltask, bstp_ifstate, ifp); 2039 if_linkstatehook_add(ifp, &bp->bp_ltask); 2040 2041 return (bp); 2042 } 2043 2044 void 2045 bstp_delete(struct bstp_port *bp) 2046 { 2047 struct bstp_state *bs = bp->bp_bs; 2048 struct ifnet *ifp; 2049 2050 if (!bp->bp_active) 2051 panic("not a bstp member"); 2052 2053 if ((ifp = if_get(bp->bp_ifindex)) != NULL) 2054 if_linkstatehook_del(ifp, &bp->bp_ltask); 2055 if_put(ifp); 2056 2057 LIST_REMOVE(bp, bp_next); 2058 free(bp, M_DEVBUF, sizeof *bp); 2059 bstp_initialization(bs); 2060 } 2061 2062 u_int8_t 2063 bstp_getstate(struct bstp_state *bs, struct bstp_port *bp) 2064 { 2065 u_int8_t state = bp->bp_state; 2066 2067 if (bs->bs_protover != BSTP_PROTO_STP) 2068 return (state); 2069 2070 /* 2071 * Translate RSTP roles and states to STP port states 2072 * (IEEE Std 802.1D-2004 Table 17-1). 2073 */ 2074 if (bp->bp_role == BSTP_ROLE_DISABLED) 2075 state = BSTP_IFSTATE_DISABLED; 2076 else if (bp->bp_role == BSTP_ROLE_ALTERNATE || 2077 bp->bp_role == BSTP_ROLE_BACKUP) 2078 state = BSTP_IFSTATE_BLOCKING; 2079 else if (state == BSTP_IFSTATE_DISCARDING) 2080 state = BSTP_IFSTATE_LISTENING; 2081 2082 return (state); 2083 } 2084 2085 void 2086 bstp_ifsflags(struct bstp_port *bp, u_int flags) 2087 { 2088 struct bstp_state *bs; 2089 2090 if ((flags & IFBIF_STP) == 0) 2091 return; 2092 bs = bp->bp_bs; 2093 2094 /* 2095 * Set edge status 2096 */ 2097 if (flags & IFBIF_BSTP_AUTOEDGE) { 2098 if ((bp->bp_flags & BSTP_PORT_AUTOEDGE) == 0) { 2099 bp->bp_flags |= BSTP_PORT_AUTOEDGE; 2100 2101 /* we may be able to transition straight to edge */ 2102 if (bp->bp_edge_delay_timer.active == 0) 2103 bstp_edge_delay_expiry(bs, bp); 2104 } 2105 } else 2106 bp->bp_flags &= ~BSTP_PORT_AUTOEDGE; 2107 2108 if (flags & IFBIF_BSTP_EDGE) 2109 bp->bp_operedge = 1; 2110 else 2111 bp->bp_operedge = 0; 2112 2113 /* 2114 * Set point to point status 2115 */ 2116 if (flags & IFBIF_BSTP_AUTOPTP) { 2117 if ((bp->bp_flags & BSTP_PORT_AUTOPTP) == 0) { 2118 bp->bp_flags |= BSTP_PORT_AUTOPTP; 2119 2120 bstp_ifupdstatus(bs, bp); 2121 } 2122 } else 2123 bp->bp_flags &= ~BSTP_PORT_AUTOPTP; 2124 2125 if (flags & IFBIF_BSTP_PTP) 2126 bp->bp_ptp_link = 1; 2127 else 2128 bp->bp_ptp_link = 0; 2129 } 2130 2131 int 2132 bstp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 2133 { 2134 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc; 2135 struct bstp_state *bs = sc->sc_stp; 2136 struct ifbrparam *ifbp = (struct ifbrparam *)data; 2137 struct ifbreq *ifbr = (struct ifbreq *)data; 2138 struct bridge_iflist *bif; 2139 struct ifnet *ifs; 2140 struct bstp_port *bp; 2141 int r = 0, err = 0, val; 2142 2143 switch (cmd) { 2144 case SIOCBRDGSIFPRIO: 2145 case SIOCBRDGSIFCOST: 2146 ifs = ifunit(ifbr->ifbr_ifsname); 2147 if (ifs == NULL) { 2148 err = ENOENT; 2149 break; 2150 } 2151 if (ifs->if_bridgeidx != ifp->if_index) { 2152 err = ESRCH; 2153 break; 2154 } 2155 bif = bridge_getbif(ifs); 2156 if ((bif->bif_flags & IFBIF_STP) == 0) { 2157 err = EINVAL; 2158 break; 2159 } 2160 bp = bif->bif_stp; 2161 break; 2162 default: 2163 break; 2164 } 2165 if (err) 2166 return (err); 2167 2168 switch (cmd) { 2169 case SIOCBRDGGPRI: 2170 ifbp->ifbrp_prio = bs->bs_bridge_priority; 2171 break; 2172 case SIOCBRDGSPRI: 2173 val = ifbp->ifbrp_prio; 2174 if (val < 0 || val > BSTP_MAX_PRIORITY) { 2175 err = EINVAL; 2176 break; 2177 } 2178 2179 /* Limit to steps of 4096 */ 2180 val -= val % 4096; 2181 bs->bs_bridge_priority = val; 2182 r = 1; 2183 break; 2184 case SIOCBRDGGMA: 2185 ifbp->ifbrp_maxage = bs->bs_bridge_max_age >> 8; 2186 break; 2187 case SIOCBRDGSMA: 2188 val = ifbp->ifbrp_maxage; 2189 2190 /* convert seconds to ticks */ 2191 val *= BSTP_TICK_VAL; 2192 2193 if (val < BSTP_MIN_MAX_AGE || val > BSTP_MAX_MAX_AGE) { 2194 err = EINVAL; 2195 break; 2196 } 2197 bs->bs_bridge_max_age = val; 2198 r = 1; 2199 break; 2200 case SIOCBRDGGHT: 2201 ifbp->ifbrp_hellotime = bs->bs_bridge_htime >> 8; 2202 break; 2203 case SIOCBRDGSHT: 2204 val = ifbp->ifbrp_hellotime; 2205 2206 /* convert seconds to ticks */ 2207 val *= BSTP_TICK_VAL; 2208 2209 /* value can only be changed in leagacy stp mode */ 2210 if (bs->bs_protover != BSTP_PROTO_STP) { 2211 err = EPERM; 2212 break; 2213 } 2214 if (val < BSTP_MIN_HELLO_TIME || val > BSTP_MAX_HELLO_TIME) { 2215 err = EINVAL; 2216 break; 2217 } 2218 bs->bs_bridge_htime = val; 2219 r = 1; 2220 break; 2221 case SIOCBRDGGFD: 2222 ifbp->ifbrp_fwddelay = bs->bs_bridge_fdelay >> 8; 2223 break; 2224 case SIOCBRDGSFD: 2225 val = ifbp->ifbrp_fwddelay; 2226 2227 /* convert seconds to ticks */ 2228 val *= BSTP_TICK_VAL; 2229 2230 if (val < BSTP_MIN_FORWARD_DELAY || 2231 val > BSTP_MAX_FORWARD_DELAY) { 2232 err = EINVAL; 2233 break; 2234 } 2235 bs->bs_bridge_fdelay = val; 2236 r = 1; 2237 break; 2238 case SIOCBRDGSTXHC: 2239 val = ifbp->ifbrp_txhc; 2240 2241 if (val < BSTP_MIN_HOLD_COUNT || val > BSTP_MAX_HOLD_COUNT) { 2242 err = EINVAL; 2243 break; 2244 } 2245 bs->bs_txholdcount = val; 2246 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) 2247 bp->bp_txcount = 0; 2248 break; 2249 case SIOCBRDGSIFPRIO: 2250 val = ifbr->ifbr_priority; 2251 if (val < 0 || val > BSTP_MAX_PORT_PRIORITY) 2252 return (EINVAL); 2253 2254 /* Limit to steps of 16 */ 2255 val -= val % 16; 2256 bp->bp_priority = val; 2257 r = 1; 2258 break; 2259 case SIOCBRDGSIFCOST: 2260 val = ifbr->ifbr_path_cost; 2261 if (val > BSTP_MAX_PATH_COST) { 2262 err = EINVAL; 2263 break; 2264 } 2265 if (val == 0) { /* use auto */ 2266 bp->bp_flags &= ~BSTP_PORT_ADMCOST; 2267 bp->bp_path_cost = bstp_calc_path_cost(bp); 2268 } else { 2269 bp->bp_path_cost = val; 2270 bp->bp_flags |= BSTP_PORT_ADMCOST; 2271 } 2272 r = 1; 2273 break; 2274 case SIOCBRDGSPROTO: 2275 val = ifbp->ifbrp_proto; 2276 2277 /* Supported protocol versions */ 2278 switch (val) { 2279 case BSTP_PROTO_STP: 2280 case BSTP_PROTO_RSTP: 2281 bs->bs_protover = val; 2282 bs->bs_bridge_htime = BSTP_DEFAULT_HELLO_TIME; 2283 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) { 2284 /* reinit state */ 2285 bp->bp_infois = BSTP_INFO_DISABLED; 2286 bp->bp_txcount = 0; 2287 bstp_set_port_proto(bp, bs->bs_protover); 2288 bstp_set_port_role(bp, BSTP_ROLE_DISABLED); 2289 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE); 2290 bstp_timer_stop(&bp->bp_recent_backup_timer); 2291 } 2292 r = 1; 2293 break; 2294 default: 2295 err = EINVAL; 2296 } 2297 break; 2298 default: 2299 break; 2300 } 2301 2302 if (r) 2303 bstp_initialization(bs); 2304 2305 return (err); 2306 } 2307