• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /macosx-10.10.1/xnu-2782.1.97/bsd/net/

Lines Matching refs:bp

214 bstp_transmit(struct bstp_state *bs, struct bstp_port *bp)
223 if (bp->bp_hello_timer.active == 0) {
225 bstp_hello_timer_expiry(bs, bp);
228 if (bp->bp_txcount > bs->bs_txholdcount)
232 if (bp->bp_protover == BSTP_PROTO_RSTP) {
233 bstp_transmit_bpdu(bs, bp);
234 bp->bp_tc_ack = 0;
236 switch (bp->bp_role) {
238 bstp_transmit_bpdu(bs, bp);
239 bp->bp_tc_ack = 0;
243 bstp_transmit_tcn(bs, bp);
247 bstp_timer_start(&bp->bp_hello_timer, bp->bp_desg_htime);
248 bp->bp_flags &= ~BSTP_PORT_NEWINFO;
252 bstp_transmit_bpdu(struct bstp_state *bs, struct bstp_port *bp)
258 bpdu.cbu_rootpri = htons(bp->bp_desg_pv.pv_root_id >> 48);
259 PV2ADDR(bp->bp_desg_pv.pv_root_id, bpdu.cbu_rootaddr);
261 bpdu.cbu_rootpathcost = htonl(bp->bp_desg_pv.pv_cost);
263 bpdu.cbu_bridgepri = htons(bp->bp_desg_pv.pv_dbridge_id >> 48);
264 PV2ADDR(bp->bp_desg_pv.pv_dbridge_id, bpdu.cbu_bridgeaddr);
266 bpdu.cbu_portid = htons(bp->bp_port_id);
267 bpdu.cbu_messageage = htons(bp->bp_desg_msg_age);
268 bpdu.cbu_maxage = htons(bp->bp_desg_max_age);
269 bpdu.cbu_hellotime = htons(bp->bp_desg_htime);
270 bpdu.cbu_forwarddelay = htons(bp->bp_desg_fdelay);
272 bpdu.cbu_flags = bstp_pdu_flags(bp);
274 switch (bp->bp_protover) {
284 bstp_send_bpdu(bs, bp, &bpdu);
288 bstp_transmit_tcn(struct bstp_state *bs, struct bstp_port *bp)
291 struct ifnet *ifp = bp->bp_ifp;
298 KASSERT(bp == bs->bs_root_port, ("%s: bad root port\n", __func__));
325 bp->bp_txcount++;
330 bstp_decode_bpdu(struct bstp_port *bp, struct bstp_cbpdu *cpdu,
359 cu->cu_pv.pv_port_id = bp->bp_port_id;
403 bstp_send_bpdu(struct bstp_state *bs, struct bstp_port *bp,
412 ifp = bp->bp_ifp;
454 bp->bp_txcount++;
475 bstp_pdu_flags(struct bstp_port *bp)
479 if (bp->bp_proposing && bp->bp_state != BSTP_IFSTATE_FORWARDING)
482 if (bp->bp_agree)
485 if (bp->bp_tc_timer.active)
488 if (bp->bp_tc_ack)
491 switch (bp->bp_state) {
501 switch (bp->bp_role) {
520 switch (bp->bp_protover) {
532 bstp_input(struct bstp_port *bp, __unused struct ifnet *ifp, struct mbuf *m)
534 struct bstp_state *bs = bp->bp_bs;
539 if (bp->bp_active == 0) {
577 if (tpdu.tbu_protover != bp->bp_protover) {
582 if (bp->bp_flags & BSTP_PORT_CANMIGRATE)
583 bstp_set_port_proto(bp, tpdu.tbu_protover);
589 bp->bp_operedge = 0;
590 bstp_timer_start(&bp->bp_edge_delay_timer,
595 bstp_received_stp(bs, bp, &m, &tpdu);
599 bstp_received_rstp(bs, bp, &m, &tpdu);
610 bstp_received_stp(struct bstp_state *bs, struct bstp_port *bp,
614 struct bstp_config_unit *cu = &bp->bp_msg_cu;
620 bstp_received_tcn(bs, bp, &tu);
628 bstp_decode_bpdu(bp, &cpdu, cu);
629 bstp_received_bpdu(bs, bp, cu);
635 bstp_received_rstp(struct bstp_state *bs, struct bstp_port *bp,
639 struct bstp_config_unit *cu = &bp->bp_msg_cu;
649 bstp_decode_bpdu(bp, &cpdu, cu);
650 bstp_received_bpdu(bs, bp, cu);
654 bstp_received_tcn(__unused struct bstp_state *bs, struct bstp_port *bp,
657 bp->bp_rcvdtcn = 1;
658 bstp_update_tc(bp);
662 bstp_received_bpdu(struct bstp_state *bs, struct bstp_port *bp,
670 switch (bp->bp_infois) {
676 type = bstp_pdu_rcvtype(bp, cu);
681 bp->bp_agreed = 0;
682 bp->bp_proposing = 0;
685 bp->bp_proposed = 1;
687 bp->bp_rcvdtc = 1;
689 bp->bp_rcvdtca = 1;
691 if (bp->bp_agree &&
692 !bstp_pdu_bettersame(bp, BSTP_INFO_RECEIVED))
693 bp->bp_agree = 0;
696 bp->bp_port_pv = cu->cu_pv;
697 bp->bp_port_msg_age = cu->cu_message_age;
698 bp->bp_port_max_age = cu->cu_max_age;
699 bp->bp_port_fdelay = cu->cu_forward_delay;
700 bp->bp_port_htime =
705 bstp_set_timer_msgage(bp);
707 bp->bp_infois = BSTP_INFO_RECEIVED;
713 bp->bp_proposed = 1;
715 bp->bp_rcvdtc = 1;
717 bp->bp_rcvdtca = 1;
720 bstp_set_timer_msgage(bp);
725 bp->bp_agreed = 1;
726 bp->bp_proposing = 0;
735 if (cu->cu_agree && bp->bp_ptp_link) {
736 bp->bp_agreed = 1;
737 bp->bp_proposing = 0;
739 bp->bp_agreed = 0;
742 bp->bp_rcvdtc = 1;
744 bp->bp_rcvdtca = 1;
751 bstp_update_state(bs, bp);
755 bstp_pdu_rcvtype(struct bstp_port *bp, struct bstp_config_unit *cu)
764 if (bstp_info_superior(&bp->bp_port_pv, &cu->cu_pv))
767 else if (bstp_info_cmp(&bp->bp_port_pv, &cu->cu_pv) ==
769 if (bp->bp_port_msg_age != cu->cu_message_age ||
770 bp->bp_port_max_age != cu->cu_max_age ||
771 bp->bp_port_fdelay != cu->cu_forward_delay ||
772 bp->bp_port_htime != cu->cu_hello_time)
787 if (bstp_info_cmp(&bp->bp_port_pv, &cu->cu_pv) <= INFO_SAME)
800 bstp_pdu_bettersame(struct bstp_port *bp, int newinfo)
803 bp->bp_infois == BSTP_INFO_RECEIVED &&
804 bstp_info_cmp(&bp->bp_port_pv, &bp->bp_msg_cu.cu_pv) >= INFO_SAME)
808 bp->bp_infois == BSTP_INFO_MINE &&
809 bstp_info_cmp(&bp->bp_port_pv, &bp->bp_desg_pv) >= INFO_SAME)
862 struct bstp_port *bp, *rbp = NULL;
874 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
875 if (bp->bp_infois != BSTP_INFO_RECEIVED)
878 pv = bp->bp_port_pv;
879 pv.pv_cost += bp->bp_path_cost;
891 bs->bs_root_msg_age = bp->bp_port_msg_age +
893 bs->bs_root_max_age = bp->bp_port_max_age;
894 bs->bs_root_fdelay = bp->bp_port_fdelay;
895 bs->bs_root_htime = bp->bp_port_htime;
896 rbp = bp;
900 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
902 bp->bp_desg_pv.pv_root_id = bs->bs_root_pv.pv_root_id;
903 bp->bp_desg_pv.pv_cost = bs->bs_root_pv.pv_cost;
904 bp->bp_desg_pv.pv_dbridge_id = bs->bs_bridge_pv.pv_dbridge_id;
905 bp->bp_desg_pv.pv_dport_id = bp->bp_port_id;
906 bp->bp_desg_pv.pv_port_id = bp->bp_port_id;
909 bp->bp_desg_msg_age = bs->bs_root_msg_age;
910 bp->bp_desg_max_age = bs->bs_root_max_age;
911 bp->bp_desg_fdelay = bs->bs_root_fdelay;
912 bp->bp_desg_htime = bs->bs_bridge_htime;
915 switch (bp->bp_infois) {
917 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
921 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
922 bstp_update_info(bp);
926 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
928 if (bstp_info_cmp(&bp->bp_port_pv,
929 &bp->bp_desg_pv) != INFO_SAME ||
931 (bp->bp_port_msg_age != rbp->bp_port_msg_age ||
932 bp->bp_port_max_age != rbp->bp_port_max_age ||
933 bp->bp_port_fdelay != rbp->bp_port_fdelay ||
934 bp->bp_port_htime != rbp->bp_port_htime)))
935 bstp_update_info(bp);
939 if (bp == rbp) {
944 bstp_set_port_role(bp, BSTP_ROLE_ROOT);
945 bs->bs_root_port = bp;
946 } else if (bstp_info_cmp(&bp->bp_port_pv,
947 &bp->bp_desg_pv) == INFO_BETTER) {
952 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
953 bstp_update_info(bp);
956 bp->bp_port_pv.pv_dbridge_id,
962 bstp_set_port_role(bp,
969 bstp_set_port_role(bp,
979 bstp_update_state(struct bstp_state *bs, struct bstp_port *bp)
999 bstp_update_roles(bs, bp);
1000 bstp_update_tc(bp);
1004 bstp_update_roles(struct bstp_state *bs, struct bstp_port *bp)
1006 switch (bp->bp_role) {
1009 if (bp->bp_sync || !bp->bp_synced || bp->bp_reroot) {
1010 bp->bp_sync = 0;
1011 bp->bp_synced = 1;
1012 bp->bp_reroot = 0;
1018 if ((bs->bs_allsynced && !bp->bp_agree) ||
1019 (bp->bp_proposed && bp->bp_agree)) {
1020 bp->bp_proposed = 0;
1021 bp->bp_agree = 1;
1022 bp->bp_flags |= BSTP_PORT_NEWINFO;
1024 bp->bp_ifp->if_xname);
1027 if (bp->bp_proposed && !bp->bp_agree) {
1029 bp->bp_proposed = 0;
1031 bp->bp_ifp->if_xname);
1035 if (bp->bp_sync || !bp->bp_synced || bp->bp_reroot) {
1036 bp->bp_sync = 0;
1037 bp->bp_synced = 1;
1038 bp->bp_reroot = 0;
1039 DPRINTF("%s -> ALTERNATE_PORT\n", bp->bp_ifp->if_xname);
1044 if (bp->bp_state != BSTP_IFSTATE_FORWARDING && !bp->bp_reroot) {
1046 DPRINTF("%s -> ROOT_REROOT\n", bp->bp_ifp->if_xname);
1049 if ((bs->bs_allsynced && !bp->bp_agree) ||
1050 (bp->bp_proposed && bp->bp_agree)) {
1051 bp->bp_proposed = 0;
1052 bp->bp_sync = 0;
1053 bp->bp_agree = 1;
1054 bp->bp_flags |= BSTP_PORT_NEWINFO;
1055 DPRINTF("%s -> ROOT_AGREED\n", bp->bp_ifp->if_xname);
1058 if (bp->bp_proposed && !bp->bp_agree) {
1060 bp->bp_proposed = 0;
1061 DPRINTF("%s -> ROOT_PROPOSED\n", bp->bp_ifp->if_xname);
1064 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
1065 (bp->bp_forward_delay_timer.active == 0 ||
1066 (bstp_rerooted(bs, bp) &&
1067 bp->bp_recent_backup_timer.active == 0 &&
1068 bp->bp_protover == BSTP_PROTO_RSTP))) {
1069 switch (bp->bp_state) {
1071 bstp_set_port_state(bp, BSTP_IFSTATE_LEARNING);
1074 bstp_set_port_state(bp,
1080 if (bp->bp_state == BSTP_IFSTATE_FORWARDING && bp->bp_reroot) {
1081 bp->bp_reroot = 0;
1082 DPRINTF("%s -> ROOT_REROOTED\n", bp->bp_ifp->if_xname);
1087 if (bp->bp_recent_root_timer.active == 0 && bp->bp_reroot) {
1088 bp->bp_reroot = 0;
1090 bp->bp_ifp->if_xname);
1093 if ((bp->bp_state == BSTP_IFSTATE_DISCARDING &&
1094 !bp->bp_synced) || (bp->bp_agreed && !bp->bp_synced) ||
1095 (bp->bp_operedge && !bp->bp_synced) ||
1096 (bp->bp_sync && bp->bp_synced)) {
1097 bstp_timer_stop(&bp->bp_recent_root_timer);
1098 bp->bp_synced = 1;
1099 bp->bp_sync = 0;
1101 bp->bp_ifp->if_xname);
1104 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
1105 !bp->bp_agreed && !bp->bp_proposing &&
1106 !bp->bp_operedge) {
1107 bp->bp_proposing = 1;
1108 bp->bp_flags |= BSTP_PORT_NEWINFO;
1109 bstp_timer_start(&bp->bp_edge_delay_timer,
1110 (bp->bp_ptp_link ? BSTP_DEFAULT_MIGRATE_DELAY :
1111 bp->bp_desg_max_age));
1113 bp->bp_ifp->if_xname);
1116 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
1117 (bp->bp_forward_delay_timer.active == 0 || bp->bp_agreed ||
1118 bp->bp_operedge) &&
1119 (bp->bp_recent_root_timer.active == 0 || !bp->bp_reroot) &&
1120 !bp->bp_sync) {
1122 if (bp->bp_agreed)
1123 DPRINTF("%s -> AGREED\n", bp->bp_ifp->if_xname);
1129 if (bp->bp_agreed || bp->bp_operedge ||
1130 bp->bp_state == BSTP_IFSTATE_LEARNING) {
1131 bstp_set_port_state(bp,
1133 bp->bp_agreed = bp->bp_protover;
1134 } else if (bp->bp_state == BSTP_IFSTATE_DISCARDING)
1135 bstp_set_port_state(bp, BSTP_IFSTATE_LEARNING);
1138 if (((bp->bp_sync && !bp->bp_synced) ||
1139 (bp->bp_reroot && bp->bp_recent_root_timer.active) ||
1140 (bp->bp_flags & BSTP_PORT_DISPUTED)) && !bp->bp_operedge &&
1141 bp->bp_state != BSTP_IFSTATE_DISCARDING) {
1142 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1143 bp->bp_flags &= ~BSTP_PORT_DISPUTED;
1144 bstp_timer_start(&bp->bp_forward_delay_timer,
1145 bp->bp_protover == BSTP_PROTO_RSTP ?
1146 bp->bp_desg_htime : bp->bp_desg_fdelay);
1148 bp->bp_ifp->if_xname);
1153 if (bp->bp_flags & BSTP_PORT_NEWINFO)
1154 bstp_transmit(bs, bp);
1158 bstp_update_tc(struct bstp_port *bp)
1160 switch (bp->bp_tcstate) {
1162 if ((bp->bp_role != BSTP_ROLE_DESIGNATED &&
1163 bp->bp_role != BSTP_ROLE_ROOT) || bp->bp_operedge)
1164 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1166 if (bp->bp_rcvdtcn)
1167 bstp_set_port_tc(bp, BSTP_TCSTATE_TCN);
1168 if (bp->bp_rcvdtc)
1169 bstp_set_port_tc(bp, BSTP_TCSTATE_TC);
1171 if (bp->bp_tc_prop && !bp->bp_operedge)
1172 bstp_set_port_tc(bp, BSTP_TCSTATE_PROPAG);
1174 if (bp->bp_rcvdtca)
1175 bstp_set_port_tc(bp, BSTP_TCSTATE_ACK);
1179 if ((bp->bp_state == BSTP_IFSTATE_LEARNING ||
1180 bp->bp_state == BSTP_IFSTATE_FORWARDING) &&
1181 bp->bp_fdbflush == 0)
1182 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1186 if (bp->bp_rcvdtc || bp->bp_rcvdtcn || bp->bp_rcvdtca ||
1187 bp->bp_tc_prop)
1188 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1189 else if (bp->bp_role != BSTP_ROLE_DESIGNATED &&
1190 bp->bp_role != BSTP_ROLE_ROOT &&
1191 bp->bp_state == BSTP_IFSTATE_DISCARDING)
1192 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
1194 if ((bp->bp_role == BSTP_ROLE_DESIGNATED ||
1195 bp->bp_role == BSTP_ROLE_ROOT) &&
1196 bp->bp_state == BSTP_IFSTATE_FORWARDING &&
1197 !bp->bp_operedge)
1198 bstp_set_port_tc(bp, BSTP_TCSTATE_DETECTED);
1208 bp->bp_ifp->if_xname);
1215 bstp_update_info(struct bstp_port *bp)
1217 struct bstp_state *bs = bp->bp_bs;
1219 bp->bp_proposing = 0;
1220 bp->bp_proposed = 0;
1222 if (bp->bp_agreed && !bstp_pdu_bettersame(bp, BSTP_INFO_MINE))
1223 bp->bp_agreed = 0;
1225 if (bp->bp_synced && !bp->bp_agreed) {
1226 bp->bp_synced = 0;
1231 bp->bp_port_pv = bp->bp_desg_pv;
1232 bp->bp_port_msg_age = bp->bp_desg_msg_age;
1233 bp->bp_port_max_age = bp->bp_desg_max_age;
1234 bp->bp_port_fdelay = bp->bp_desg_fdelay;
1235 bp->bp_port_htime = bp->bp_desg_htime;
1236 bp->bp_infois = BSTP_INFO_MINE;
1239 bp->bp_flags |= BSTP_PORT_NEWINFO;
1244 bstp_set_other_tcprop(struct bstp_port *bp)
1246 struct bstp_state *bs = bp->bp_bs;
1252 if (bp2 == bp)
1261 struct bstp_port *bp;
1265 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
1266 bp->bp_reroot = 1;
1272 struct bstp_port *bp;
1276 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1277 bp->bp_sync = 1;
1278 bp->bp_synced = 0; /* Not explicit in spec */
1285 bstp_set_port_state(struct bstp_port *bp, int state)
1287 if (bp->bp_state == state)
1290 bp->bp_state = state;
1292 switch (bp->bp_state) {
1295 bp->bp_ifp->if_xname);
1300 bp->bp_ifp->if_xname);
1302 bstp_timer_start(&bp->bp_forward_delay_timer,
1303 bp->bp_protover == BSTP_PROTO_RSTP ?
1304 bp->bp_desg_htime : bp->bp_desg_fdelay);
1309 bp->bp_ifp->if_xname);
1311 bstp_timer_stop(&bp->bp_forward_delay_timer);
1313 bp->bp_forward_transitions++;
1318 bstp_task_enqueue(&bp->bp_statetask);
1322 bstp_set_port_role(struct bstp_port *bp, int role)
1324 struct bstp_state *bs = bp->bp_bs;
1326 if (bp->bp_role == role)
1330 switch (bp->bp_role) {
1332 bstp_timer_start(&bp->bp_forward_delay_timer,
1333 bp->bp_desg_max_age);
1337 bstp_timer_start(&bp->bp_recent_backup_timer,
1338 bp->bp_desg_htime * 2);
1341 bstp_timer_start(&bp->bp_forward_delay_timer,
1342 bp->bp_desg_fdelay);
1343 bp->bp_sync = 0;
1344 bp->bp_synced = 1;
1345 bp->bp_reroot = 0;
1349 bstp_timer_start(&bp->bp_recent_root_timer,
1354 bp->bp_role = role;
1356 bp->bp_proposing = 0;
1360 switch (bp->bp_role) {
1365 bp->bp_ifp->if_xname);
1366 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1367 bstp_timer_stop(&bp->bp_recent_root_timer);
1368 bstp_timer_latch(&bp->bp_forward_delay_timer);
1369 bp->bp_sync = 0;
1370 bp->bp_synced = 1;
1371 bp->bp_reroot = 0;
1376 bp->bp_ifp->if_xname);
1377 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1378 bstp_timer_latch(&bp->bp_recent_root_timer);
1379 bp->bp_proposing = 0;
1384 bp->bp_ifp->if_xname);
1385 bstp_timer_start(&bp->bp_hello_timer,
1386 bp->bp_desg_htime);
1387 bp->bp_agree = 0;
1392 bstp_update_tc(bp);
1396 bstp_set_port_proto(struct bstp_port *bp, int proto)
1398 struct bstp_state *bs = bp->bp_bs;
1404 bstp_timer_stop(&bp->bp_migrate_delay_timer);
1406 bp->bp_operedge = 0;
1408 if (bp->bp_path_cost > 65535)
1409 bp->bp_path_cost = 65535;
1413 bstp_timer_start(&bp->bp_migrate_delay_timer,
1422 bp->bp_protover = proto;
1423 bp->bp_flags &= ~BSTP_PORT_CANMIGRATE;
1427 bstp_set_port_tc(struct bstp_port *bp, int state)
1429 struct bstp_state *bs = bp->bp_bs;
1431 bp->bp_tcstate = state;
1434 switch (bp->bp_tcstate) {
1436 DPRINTF("%s -> TC_ACTIVE\n", bp->bp_ifp->if_xname);
1441 bstp_timer_stop(&bp->bp_tc_timer);
1443 bp->bp_fdbflush = 1;
1444 bstp_task_enqueue(&bp->bp_rtagetask);
1445 bp->bp_tc_ack = 0;
1446 DPRINTF("%s -> TC_INACTIVE\n", bp->bp_ifp->if_xname);
1450 bp->bp_rcvdtc = 0;
1451 bp->bp_rcvdtcn = 0;
1452 bp->bp_rcvdtca = 0;
1453 bp->bp_tc_prop = 0;
1454 DPRINTF("%s -> TC_LEARNING\n", bp->bp_ifp->if_xname);
1458 bstp_set_timer_tc(bp);
1459 bstp_set_other_tcprop(bp);
1461 bp->bp_flags |= BSTP_PORT_NEWINFO;
1462 bstp_transmit(bs, bp);
1465 DPRINTF("%s -> TC_DETECTED\n", bp->bp_ifp->if_xname);
1466 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1470 bstp_set_timer_tc(bp);
1471 DPRINTF("%s -> TC_TCN\n", bp->bp_ifp->if_xname);
1474 bp->bp_rcvdtc = 0;
1475 bp->bp_rcvdtcn = 0;
1476 if (bp->bp_role == BSTP_ROLE_DESIGNATED)
1477 bp->bp_tc_ack = 1;
1479 bstp_set_other_tcprop(bp);
1480 DPRINTF("%s -> TC_TC\n", bp->bp_ifp->if_xname);
1481 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1486 bp->bp_fdbflush = 1;
1487 bstp_task_enqueue(&bp->bp_rtagetask);
1488 bp->bp_tc_prop = 0;
1489 bstp_set_timer_tc(bp);
1490 DPRINTF("%s -> TC_PROPAG\n", bp->bp_ifp->if_xname);
1491 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1495 bstp_timer_stop(&bp->bp_tc_timer);
1496 bp->bp_rcvdtca = 0;
1497 DPRINTF("%s -> TC_ACK\n", bp->bp_ifp->if_xname);
1498 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1504 bstp_set_timer_tc(struct bstp_port *bp)
1506 struct bstp_state *bs = bp->bp_bs;
1508 if (bp->bp_tc_timer.active)
1511 switch (bp->bp_protover) {
1513 bstp_timer_start(&bp->bp_tc_timer,
1514 bp->bp_desg_htime + BSTP_TICK_VAL);
1515 bp->bp_flags |= BSTP_PORT_NEWINFO;
1519 bstp_timer_start(&bp->bp_tc_timer,
1526 bstp_set_timer_msgage(struct bstp_port *bp)
1528 if (bp->bp_port_msg_age + BSTP_MESSAGE_AGE_INCR <=
1529 bp->bp_port_max_age) {
1530 bstp_timer_start(&bp->bp_message_age_timer,
1531 bp->bp_port_htime * 3);
1534 bstp_timer_start(&bp->bp_message_age_timer, 0);
1538 bstp_rerooted(struct bstp_state *bs, struct bstp_port *bp)
1544 if (bp2 == bp)
1609 struct bstp_port *bp;
1617 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
1618 bp->bp_txcount = 0;
1626 struct bstp_port *bp;
1641 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1643 bp->bp_infois = BSTP_INFO_DISABLED;
1644 bp->bp_txcount = 0;
1645 bstp_set_port_proto(bp, bs->bs_protover);
1646 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
1647 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
1648 bstp_timer_stop(&bp->bp_recent_backup_timer);
1672 bstp_set_port_priority(struct bstp_port *bp, int pri)
1674 struct bstp_state *bs = bp->bp_bs;
1683 bp->bp_priority = pri;
1690 bstp_set_path_cost(struct bstp_port *bp, uint32_t path_cost)
1692 struct bstp_state *bs = bp->bp_bs;
1698 if (bp->bp_protover == BSTP_PROTO_STP && path_cost > 65535)
1704 bp->bp_flags &= ~BSTP_PORT_ADMCOST;
1705 bp->bp_path_cost = bstp_calc_path_cost(bp);
1707 bp->bp_path_cost = path_cost;
1708 bp->bp_flags |= BSTP_PORT_ADMCOST;
1716 bstp_set_edge(struct bstp_port *bp, int set)
1718 struct bstp_state *bs = bp->bp_bs;
1721 if ((bp->bp_operedge = set) == 0)
1722 bp->bp_flags &= ~BSTP_PORT_ADMEDGE;
1724 bp->bp_flags |= BSTP_PORT_ADMEDGE;
1730 bstp_set_autoedge(struct bstp_port *bp, int set)
1732 struct bstp_state *bs = bp->bp_bs;
1736 bp->bp_flags |= BSTP_PORT_AUTOEDGE;
1738 if (bp->bp_edge_delay_timer.active == 0)
1739 bstp_edge_delay_expiry(bs, bp);
1741 bp->bp_flags &= ~BSTP_PORT_AUTOEDGE;
1747 bstp_set_ptp(struct bstp_port *bp, int set)
1749 struct bstp_state *bs = bp->bp_bs;
1752 bp->bp_ptp_link = set;
1758 bstp_set_autoptp(struct bstp_port *bp, int set)
1760 struct bstp_state *bs = bp->bp_bs;
1764 bp->bp_flags |= BSTP_PORT_AUTOPTP;
1765 if (bp->bp_role != BSTP_ROLE_DISABLED)
1766 bstp_ifupdstatus(bs, bp);
1768 bp->bp_flags &= ~BSTP_PORT_AUTOPTP;
1777 bstp_calc_path_cost(struct bstp_port *bp)
1779 struct ifnet *ifp = bp->bp_ifp;
1783 if (bp->bp_flags & BSTP_PORT_ADMCOST)
1784 return bp->bp_path_cost;
1786 if (bp->bp_if_link_state == LINK_STATE_DOWN) {
1788 bp->bp_flags |= BSTP_PORT_PNDCOST;
1802 if (bp->bp_protover == BSTP_PROTO_STP && path_cost > 65535)
1815 struct bstp_port *bp = (struct bstp_port *)arg;
1816 struct bstp_state *bs = bp->bp_bs;
1818 if (bp->bp_active == 1 && bs->bs_state_cb != NULL)
1819 (*bs->bs_state_cb)(bp->bp_ifp, bp->bp_state);
1829 struct bstp_port *bp = (struct bstp_port *)arg;
1830 struct bstp_state *bs = bp->bp_bs;
1834 switch (bp->bp_protover) {
1837 age = bp->bp_desg_fdelay / BSTP_TICK_VAL;
1846 if (bp->bp_active == 1 && bs->bs_rtage_cb != NULL)
1847 (*bs->bs_rtage_cb)(bp->bp_ifp, age);
1851 bp->bp_fdbflush = 0;
1859 struct bstp_port *bp;
1865 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1866 if (bp->bp_ifp == ifp) {
1867 bstp_ifupdstatus(bs, bp);
1868 bstp_update_state(bs, bp);
1881 bstp_ifupdstatus(struct bstp_state *bs, struct bstp_port *bp)
1883 struct ifnet *ifp = bp->bp_ifp;
1895 if (bp->bp_flags & BSTP_PORT_AUTOPTP) {
1896 bp->bp_ptp_link =
1901 if (bp->bp_flags & BSTP_PORT_PNDCOST) {
1902 bp->bp_path_cost = bstp_calc_path_cost(bp);
1903 bp->bp_flags &= ~BSTP_PORT_PNDCOST;
1906 if (bp->bp_role == BSTP_ROLE_DISABLED)
1907 bstp_enable_port(bs, bp);
1909 if (bp->bp_role != BSTP_ROLE_DISABLED) {
1910 bstp_disable_port(bs, bp);
1911 if ((bp->bp_flags & BSTP_PORT_ADMEDGE) &&
1912 bp->bp_protover == BSTP_PROTO_RSTP)
1913 bp->bp_operedge = 1;
1919 if (bp->bp_infois != BSTP_INFO_DISABLED)
1920 bstp_disable_port(bs, bp);
1924 bstp_enable_port(struct bstp_state *bs, struct bstp_port *bp)
1926 bp->bp_infois = BSTP_INFO_AGED;
1931 bstp_disable_port(struct bstp_state *bs, struct bstp_port *bp)
1933 bp->bp_infois = BSTP_INFO_DISABLED;
1941 struct bstp_port *bp;
1951 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
1952 bstp_ifupdstatus(bs, bp);
1956 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1958 bstp_timer_expired(&bp->bp_tc_timer);
1959 bstp_timer_expired(&bp->bp_recent_root_timer);
1960 bstp_timer_expired(&bp->bp_forward_delay_timer);
1961 bstp_timer_expired(&bp->bp_recent_backup_timer);
1963 if (bstp_timer_expired(&bp->bp_hello_timer))
1964 bstp_hello_timer_expiry(bs, bp);
1966 if (bstp_timer_expired(&bp->bp_message_age_timer))
1967 bstp_message_age_expiry(bs, bp);
1969 if (bstp_timer_expired(&bp->bp_migrate_delay_timer))
1970 bstp_migrate_delay_expiry(bs, bp);
1972 if (bstp_timer_expired(&bp->bp_edge_delay_timer))
1973 bstp_edge_delay_expiry(bs, bp);
1976 bstp_update_state(bs, bp);
1978 if (bp->bp_txcount > 0)
1979 bp->bp_txcount--;
2026 bstp_hello_timer_expiry(struct bstp_state *bs, struct bstp_port *bp)
2028 if ((bp->bp_flags & BSTP_PORT_NEWINFO) ||
2029 bp->bp_role == BSTP_ROLE_DESIGNATED ||
2030 (bp->bp_role == BSTP_ROLE_ROOT &&
2031 bp->bp_tc_timer.active == 1)) {
2032 bstp_timer_start(&bp->bp_hello_timer, bp->bp_desg_htime);
2033 bp->bp_flags |= BSTP_PORT_NEWINFO;
2034 bstp_transmit(bs, bp);
2039 bstp_message_age_expiry(struct bstp_state *bs, struct bstp_port *bp)
2041 if (bp->bp_infois == BSTP_INFO_RECEIVED) {
2042 bp->bp_infois = BSTP_INFO_AGED;
2044 DPRINTF("aged info on %s\n", bp->bp_ifp->if_xname);
2049 bstp_migrate_delay_expiry(__unused struct bstp_state *bs, struct bstp_port *bp)
2051 bp->bp_flags |= BSTP_PORT_CANMIGRATE;
2055 bstp_edge_delay_expiry(__unused struct bstp_state *bs, struct bstp_port *bp)
2057 if ((bp->bp_flags & BSTP_PORT_AUTOEDGE) &&
2058 bp->bp_protover == BSTP_PROTO_RSTP && bp->bp_proposing &&
2059 bp->bp_role == BSTP_ROLE_DESIGNATED) {
2060 bp->bp_operedge = 1;
2061 DPRINTF("%s -> edge port\n", bp->bp_ifp->if_xname);
2098 struct bstp_port *bp;
2138 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
2139 bp->bp_infois = BSTP_INFO_DISABLED;
2140 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
2164 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
2165 bp->bp_port_id = (bp->bp_priority << 8) |
2166 (bp->bp_ifp->if_index & 0xfff);
2167 bstp_ifupdstatus(bs, bp);
2229 struct bstp_port *bp;
2233 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
2234 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
2242 bstp_create(struct bstp_state *bs, struct bstp_port *bp, struct ifnet *ifp)
2244 bzero(bp, sizeof(struct bstp_port));
2247 bp->bp_ifp = ifp;
2248 bp->bp_bs = bs;
2249 bp->bp_priority = BSTP_DEFAULT_PORT_PRIORITY;
2250 BSTP_TASK_INIT(&bp->bp_statetask, bstp_notify_state, bp);
2251 BSTP_TASK_INIT(&bp->bp_rtagetask, bstp_notify_rtage, bp);
2254 bp->bp_infois = BSTP_INFO_DISABLED;
2255 bp->bp_flags = BSTP_PORT_AUTOEDGE|BSTP_PORT_AUTOPTP;
2256 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
2257 bstp_set_port_proto(bp, bs->bs_protover);
2258 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
2259 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
2260 bp->bp_path_cost = bstp_calc_path_cost(bp);
2266 bstp_enable(struct bstp_port *bp)
2268 struct bstp_state *bs = bp->bp_bs;
2269 struct ifnet *ifp = bp->bp_ifp;
2271 KASSERT(bp->bp_active == 0, ("already a bstp member"));
2282 LIST_INSERT_HEAD(&bs->bs_bplist, bp, bp_next);
2283 bp->bp_active = 1;
2284 bp->bp_flags |= BSTP_PORT_NEWINFO;
2286 bstp_update_roles(bs, bp);
2292 bstp_disable(struct bstp_port *bp)
2294 struct bstp_state *bs = bp->bp_bs;
2296 KASSERT(bp->bp_active == 1, ("not a bstp member"));
2299 bstp_disable_port(bs, bp);
2300 LIST_REMOVE(bp, bp_next);
2301 bp->bp_active = 0;
2310 bstp_destroy(struct bstp_port *bp)
2312 KASSERT(bp->bp_active == 0, ("port is still attached"));
2313 bstp_task_drain(&bp->bp_statetask);
2314 bstp_task_drain(&bp->bp_rtagetask);