Lines Matching refs:bp

153 bstp_transmit(struct bstp_state *bs, struct bstp_port *bp)
162 if (bp->bp_hello_timer.active == 0) {
164 bstp_hello_timer_expiry(bs, bp);
167 if (bp->bp_txcount > bs->bs_txholdcount)
171 if (bp->bp_protover == BSTP_PROTO_RSTP) {
172 bstp_transmit_bpdu(bs, bp);
173 bp->bp_tc_ack = 0;
175 switch (bp->bp_role) {
177 bstp_transmit_bpdu(bs, bp);
178 bp->bp_tc_ack = 0;
182 bstp_transmit_tcn(bs, bp);
186 bstp_timer_start(&bp->bp_hello_timer, bp->bp_desg_htime);
187 bp->bp_flags &= ~BSTP_PORT_NEWINFO;
191 bstp_transmit_bpdu(struct bstp_state *bs, struct bstp_port *bp)
197 bpdu.cbu_rootpri = htons(bp->bp_desg_pv.pv_root_id >> 48);
198 PV2ADDR(bp->bp_desg_pv.pv_root_id, bpdu.cbu_rootaddr);
200 bpdu.cbu_rootpathcost = htonl(bp->bp_desg_pv.pv_cost);
202 bpdu.cbu_bridgepri = htons(bp->bp_desg_pv.pv_dbridge_id >> 48);
203 PV2ADDR(bp->bp_desg_pv.pv_dbridge_id, bpdu.cbu_bridgeaddr);
205 bpdu.cbu_portid = htons(bp->bp_port_id);
206 bpdu.cbu_messageage = htons(bp->bp_desg_msg_age);
207 bpdu.cbu_maxage = htons(bp->bp_desg_max_age);
208 bpdu.cbu_hellotime = htons(bp->bp_desg_htime);
209 bpdu.cbu_forwarddelay = htons(bp->bp_desg_fdelay);
211 bpdu.cbu_flags = bstp_pdu_flags(bp);
213 switch (bp->bp_protover) {
223 bstp_send_bpdu(bs, bp, &bpdu);
227 bstp_transmit_tcn(struct bstp_state *bs, struct bstp_port *bp)
230 struct ifnet *ifp = bp->bp_ifp;
234 KASSERT(bp == bs->bs_root_port, ("%s: bad root port\n", __func__));
261 bp->bp_txcount++;
266 bstp_decode_bpdu(struct bstp_port *bp, struct bstp_cbpdu *cpdu,
295 cu->cu_pv.pv_port_id = bp->bp_port_id;
339 bstp_send_bpdu(struct bstp_state *bs, struct bstp_port *bp,
348 ifp = bp->bp_ifp;
390 bp->bp_txcount++;
395 bstp_pdu_flags(struct bstp_port *bp)
399 if (bp->bp_proposing && bp->bp_state != BSTP_IFSTATE_FORWARDING)
402 if (bp->bp_agree)
405 if (bp->bp_tc_timer.active)
408 if (bp->bp_tc_ack)
411 switch (bp->bp_state) {
421 switch (bp->bp_role) {
440 switch (bp->bp_protover) {
452 bstp_input(struct bstp_port *bp, struct ifnet *ifp, struct mbuf *m)
454 struct bstp_state *bs = bp->bp_bs;
459 if (bp->bp_active == 0) {
497 if (tpdu.tbu_protover != bp->bp_protover) {
502 if (bp->bp_flags & BSTP_PORT_CANMIGRATE)
503 bstp_set_port_proto(bp, tpdu.tbu_protover);
509 bp->bp_operedge = 0;
510 bstp_timer_start(&bp->bp_edge_delay_timer,
515 bstp_received_stp(bs, bp, &m, &tpdu);
519 bstp_received_rstp(bs, bp, &m, &tpdu);
529 bstp_received_stp(struct bstp_state *bs, struct bstp_port *bp,
533 struct bstp_config_unit *cu = &bp->bp_msg_cu;
539 bstp_received_tcn(bs, bp, &tu);
547 bstp_decode_bpdu(bp, &cpdu, cu);
548 bstp_received_bpdu(bs, bp, cu);
554 bstp_received_rstp(struct bstp_state *bs, struct bstp_port *bp,
558 struct bstp_config_unit *cu = &bp->bp_msg_cu;
568 bstp_decode_bpdu(bp, &cpdu, cu);
569 bstp_received_bpdu(bs, bp, cu);
573 bstp_received_tcn(struct bstp_state *bs, struct bstp_port *bp,
576 bp->bp_rcvdtcn = 1;
577 bstp_update_tc(bp);
581 bstp_received_bpdu(struct bstp_state *bs, struct bstp_port *bp,
589 switch (bp->bp_infois) {
595 type = bstp_pdu_rcvtype(bp, cu);
600 bp->bp_agreed = 0;
601 bp->bp_proposing = 0;
604 bp->bp_proposed = 1;
606 bp->bp_rcvdtc = 1;
608 bp->bp_rcvdtca = 1;
610 if (bp->bp_agree &&
611 !bstp_pdu_bettersame(bp, BSTP_INFO_RECEIVED))
612 bp->bp_agree = 0;
615 bp->bp_port_pv = cu->cu_pv;
616 bp->bp_port_msg_age = cu->cu_message_age;
617 bp->bp_port_max_age = cu->cu_max_age;
618 bp->bp_port_fdelay = cu->cu_forward_delay;
619 bp->bp_port_htime =
624 bstp_set_timer_msgage(bp);
626 bp->bp_infois = BSTP_INFO_RECEIVED;
632 bp->bp_proposed = 1;
634 bp->bp_rcvdtc = 1;
636 bp->bp_rcvdtca = 1;
639 bstp_set_timer_msgage(bp);
644 bp->bp_agreed = 1;
645 bp->bp_proposing = 0;
654 if (cu->cu_agree && bp->bp_ptp_link) {
655 bp->bp_agreed = 1;
656 bp->bp_proposing = 0;
658 bp->bp_agreed = 0;
661 bp->bp_rcvdtc = 1;
663 bp->bp_rcvdtca = 1;
670 bstp_update_state(bs, bp);
674 bstp_pdu_rcvtype(struct bstp_port *bp, struct bstp_config_unit *cu)
683 if (bstp_info_superior(&bp->bp_port_pv, &cu->cu_pv))
686 else if (bstp_info_cmp(&bp->bp_port_pv, &cu->cu_pv) ==
688 if (bp->bp_port_msg_age != cu->cu_message_age ||
689 bp->bp_port_max_age != cu->cu_max_age ||
690 bp->bp_port_fdelay != cu->cu_forward_delay ||
691 bp->bp_port_htime != cu->cu_hello_time)
706 if (bstp_info_cmp(&bp->bp_port_pv, &cu->cu_pv) <= INFO_SAME)
719 bstp_pdu_bettersame(struct bstp_port *bp, int newinfo)
722 bp->bp_infois == BSTP_INFO_RECEIVED &&
723 bstp_info_cmp(&bp->bp_port_pv, &bp->bp_msg_cu.cu_pv) >= INFO_SAME)
727 bp->bp_infois == BSTP_INFO_MINE &&
728 bstp_info_cmp(&bp->bp_port_pv, &bp->bp_desg_pv) >= INFO_SAME)
781 struct bstp_port *bp, *rbp = NULL;
793 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
794 if (bp->bp_infois != BSTP_INFO_RECEIVED)
797 pv = bp->bp_port_pv;
798 pv.pv_cost += bp->bp_path_cost;
810 bs->bs_root_msg_age = bp->bp_port_msg_age +
812 bs->bs_root_max_age = bp->bp_port_max_age;
813 bs->bs_root_fdelay = bp->bp_port_fdelay;
814 bs->bs_root_htime = bp->bp_port_htime;
815 rbp = bp;
819 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
821 bp->bp_desg_pv.pv_root_id = bs->bs_root_pv.pv_root_id;
822 bp->bp_desg_pv.pv_cost = bs->bs_root_pv.pv_cost;
823 bp->bp_desg_pv.pv_dbridge_id = bs->bs_bridge_pv.pv_dbridge_id;
824 bp->bp_desg_pv.pv_dport_id = bp->bp_port_id;
825 bp->bp_desg_pv.pv_port_id = bp->bp_port_id;
828 bp->bp_desg_msg_age = bs->bs_root_msg_age;
829 bp->bp_desg_max_age = bs->bs_root_max_age;
830 bp->bp_desg_fdelay = bs->bs_root_fdelay;
831 bp->bp_desg_htime = bs->bs_bridge_htime;
834 switch (bp->bp_infois) {
836 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
840 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
841 bstp_update_info(bp);
845 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
847 if (bstp_info_cmp(&bp->bp_port_pv,
848 &bp->bp_desg_pv) != INFO_SAME ||
850 (bp->bp_port_msg_age != rbp->bp_port_msg_age ||
851 bp->bp_port_max_age != rbp->bp_port_max_age ||
852 bp->bp_port_fdelay != rbp->bp_port_fdelay ||
853 bp->bp_port_htime != rbp->bp_port_htime)))
854 bstp_update_info(bp);
858 if (bp == rbp) {
863 bstp_set_port_role(bp, BSTP_ROLE_ROOT);
864 bs->bs_root_port = bp;
865 } else if (bstp_info_cmp(&bp->bp_port_pv,
866 &bp->bp_desg_pv) == INFO_BETTER) {
871 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
872 bstp_update_info(bp);
875 bp->bp_port_pv.pv_dbridge_id,
881 bstp_set_port_role(bp,
888 bstp_set_port_role(bp,
898 bstp_update_state(struct bstp_state *bs, struct bstp_port *bp)
918 bstp_update_roles(bs, bp);
919 bstp_update_tc(bp);
923 bstp_update_roles(struct bstp_state *bs, struct bstp_port *bp)
925 switch (bp->bp_role) {
928 if (bp->bp_sync || !bp->bp_synced || bp->bp_reroot) {
929 bp->bp_sync = 0;
930 bp->bp_synced = 1;
931 bp->bp_reroot = 0;
937 if ((bs->bs_allsynced && !bp->bp_agree) ||
938 (bp->bp_proposed && bp->bp_agree)) {
939 bp->bp_proposed = 0;
940 bp->bp_agree = 1;
941 bp->bp_flags |= BSTP_PORT_NEWINFO;
943 bp->bp_ifp->if_xname);
946 if (bp->bp_proposed && !bp->bp_agree) {
948 bp->bp_proposed = 0;
950 bp->bp_ifp->if_xname);
954 if (bp->bp_sync || !bp->bp_synced || bp->bp_reroot) {
955 bp->bp_sync = 0;
956 bp->bp_synced = 1;
957 bp->bp_reroot = 0;
958 DPRINTF("%s -> ALTERNATE_PORT\n", bp->bp_ifp->if_xname);
963 if (bp->bp_state != BSTP_IFSTATE_FORWARDING && !bp->bp_reroot) {
965 DPRINTF("%s -> ROOT_REROOT\n", bp->bp_ifp->if_xname);
968 if ((bs->bs_allsynced && !bp->bp_agree) ||
969 (bp->bp_proposed && bp->bp_agree)) {
970 bp->bp_proposed = 0;
971 bp->bp_sync = 0;
972 bp->bp_agree = 1;
973 bp->bp_flags |= BSTP_PORT_NEWINFO;
974 DPRINTF("%s -> ROOT_AGREED\n", bp->bp_ifp->if_xname);
977 if (bp->bp_proposed && !bp->bp_agree) {
979 bp->bp_proposed = 0;
980 DPRINTF("%s -> ROOT_PROPOSED\n", bp->bp_ifp->if_xname);
983 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
984 (bp->bp_forward_delay_timer.active == 0 ||
985 (bstp_rerooted(bs, bp) &&
986 bp->bp_recent_backup_timer.active == 0 &&
987 bp->bp_protover == BSTP_PROTO_RSTP))) {
988 switch (bp->bp_state) {
990 bstp_set_port_state(bp, BSTP_IFSTATE_LEARNING);
993 bstp_set_port_state(bp,
999 if (bp->bp_state == BSTP_IFSTATE_FORWARDING && bp->bp_reroot) {
1000 bp->bp_reroot = 0;
1001 DPRINTF("%s -> ROOT_REROOTED\n", bp->bp_ifp->if_xname);
1006 if (bp->bp_recent_root_timer.active == 0 && bp->bp_reroot) {
1007 bp->bp_reroot = 0;
1009 bp->bp_ifp->if_xname);
1012 if ((bp->bp_state == BSTP_IFSTATE_DISCARDING &&
1013 !bp->bp_synced) || (bp->bp_agreed && !bp->bp_synced) ||
1014 (bp->bp_operedge && !bp->bp_synced) ||
1015 (bp->bp_sync && bp->bp_synced)) {
1016 bstp_timer_stop(&bp->bp_recent_root_timer);
1017 bp->bp_synced = 1;
1018 bp->bp_sync = 0;
1020 bp->bp_ifp->if_xname);
1023 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
1024 !bp->bp_agreed && !bp->bp_proposing &&
1025 !bp->bp_operedge) {
1026 bp->bp_proposing = 1;
1027 bp->bp_flags |= BSTP_PORT_NEWINFO;
1028 bstp_timer_start(&bp->bp_edge_delay_timer,
1029 (bp->bp_ptp_link ? BSTP_DEFAULT_MIGRATE_DELAY :
1030 bp->bp_desg_max_age));
1032 bp->bp_ifp->if_xname);
1035 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
1036 (bp->bp_forward_delay_timer.active == 0 || bp->bp_agreed ||
1037 bp->bp_operedge) &&
1038 (bp->bp_recent_root_timer.active == 0 || !bp->bp_reroot) &&
1039 !bp->bp_sync) {
1040 if (bp->bp_agreed)
1041 DPRINTF("%s -> AGREED\n", bp->bp_ifp->if_xname);
1046 if (bp->bp_agreed || bp->bp_operedge ||
1047 bp->bp_state == BSTP_IFSTATE_LEARNING) {
1048 bstp_set_port_state(bp,
1050 bp->bp_agreed = bp->bp_protover;
1051 } else if (bp->bp_state == BSTP_IFSTATE_DISCARDING)
1052 bstp_set_port_state(bp, BSTP_IFSTATE_LEARNING);
1055 if (((bp->bp_sync && !bp->bp_synced) ||
1056 (bp->bp_reroot && bp->bp_recent_root_timer.active) ||
1057 (bp->bp_flags & BSTP_PORT_DISPUTED)) && !bp->bp_operedge &&
1058 bp->bp_state != BSTP_IFSTATE_DISCARDING) {
1059 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1060 bp->bp_flags &= ~BSTP_PORT_DISPUTED;
1061 bstp_timer_start(&bp->bp_forward_delay_timer,
1062 bp->bp_protover == BSTP_PROTO_RSTP ?
1063 bp->bp_desg_htime : bp->bp_desg_fdelay);
1065 bp->bp_ifp->if_xname);
1070 if (bp->bp_flags & BSTP_PORT_NEWINFO)
1071 bstp_transmit(bs, bp);
1075 bstp_update_tc(struct bstp_port *bp)
1077 switch (bp->bp_tcstate) {
1079 if ((bp->bp_role != BSTP_ROLE_DESIGNATED &&
1080 bp->bp_role != BSTP_ROLE_ROOT) || bp->bp_operedge)
1081 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1083 if (bp->bp_rcvdtcn)
1084 bstp_set_port_tc(bp, BSTP_TCSTATE_TCN);
1085 if (bp->bp_rcvdtc)
1086 bstp_set_port_tc(bp, BSTP_TCSTATE_TC);
1088 if (bp->bp_tc_prop && !bp->bp_operedge)
1089 bstp_set_port_tc(bp, BSTP_TCSTATE_PROPAG);
1091 if (bp->bp_rcvdtca)
1092 bstp_set_port_tc(bp, BSTP_TCSTATE_ACK);
1096 if ((bp->bp_state == BSTP_IFSTATE_LEARNING ||
1097 bp->bp_state == BSTP_IFSTATE_FORWARDING) &&
1098 bp->bp_fdbflush == 0)
1099 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1103 if (bp->bp_rcvdtc || bp->bp_rcvdtcn || bp->bp_rcvdtca ||
1104 bp->bp_tc_prop)
1105 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1106 else if (bp->bp_role != BSTP_ROLE_DESIGNATED &&
1107 bp->bp_role != BSTP_ROLE_ROOT &&
1108 bp->bp_state == BSTP_IFSTATE_DISCARDING)
1109 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
1111 if ((bp->bp_role == BSTP_ROLE_DESIGNATED ||
1112 bp->bp_role == BSTP_ROLE_ROOT) &&
1113 bp->bp_state == BSTP_IFSTATE_FORWARDING &&
1114 !bp->bp_operedge)
1115 bstp_set_port_tc(bp, BSTP_TCSTATE_DETECTED);
1125 bp->bp_ifp->if_xname);
1132 bstp_update_info(struct bstp_port *bp)
1134 struct bstp_state *bs = bp->bp_bs;
1136 bp->bp_proposing = 0;
1137 bp->bp_proposed = 0;
1139 if (bp->bp_agreed && !bstp_pdu_bettersame(bp, BSTP_INFO_MINE))
1140 bp->bp_agreed = 0;
1142 if (bp->bp_synced && !bp->bp_agreed) {
1143 bp->bp_synced = 0;
1148 bp->bp_port_pv = bp->bp_desg_pv;
1149 bp->bp_port_msg_age = bp->bp_desg_msg_age;
1150 bp->bp_port_max_age = bp->bp_desg_max_age;
1151 bp->bp_port_fdelay = bp->bp_desg_fdelay;
1152 bp->bp_port_htime = bp->bp_desg_htime;
1153 bp->bp_infois = BSTP_INFO_MINE;
1156 bp->bp_flags |= BSTP_PORT_NEWINFO;
1161 bstp_set_other_tcprop(struct bstp_port *bp)
1163 struct bstp_state *bs = bp->bp_bs;
1169 if (bp2 == bp)
1178 struct bstp_port *bp;
1182 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
1183 bp->bp_reroot = 1;
1189 struct bstp_port *bp;
1193 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1194 bp->bp_sync = 1;
1195 bp->bp_synced = 0; /* Not explicit in spec */
1202 bstp_set_port_state(struct bstp_port *bp, int state)
1204 if (bp->bp_state == state)
1207 bp->bp_state = state;
1209 switch (bp->bp_state) {
1212 bp->bp_ifp->if_xname);
1217 bp->bp_ifp->if_xname);
1219 bstp_timer_start(&bp->bp_forward_delay_timer,
1220 bp->bp_protover == BSTP_PROTO_RSTP ?
1221 bp->bp_desg_htime : bp->bp_desg_fdelay);
1226 bp->bp_ifp->if_xname);
1228 bstp_timer_stop(&bp->bp_forward_delay_timer);
1230 bp->bp_forward_transitions++;
1235 taskqueue_enqueue(taskqueue_swi, &bp->bp_statetask);
1239 bstp_set_port_role(struct bstp_port *bp, int role)
1241 struct bstp_state *bs = bp->bp_bs;
1243 if (bp->bp_role == role)
1247 switch (bp->bp_role) {
1249 bstp_timer_start(&bp->bp_forward_delay_timer,
1250 bp->bp_desg_max_age);
1254 bstp_timer_start(&bp->bp_recent_backup_timer,
1255 bp->bp_desg_htime * 2);
1258 bstp_timer_start(&bp->bp_forward_delay_timer,
1259 bp->bp_desg_fdelay);
1260 bp->bp_sync = 0;
1261 bp->bp_synced = 1;
1262 bp->bp_reroot = 0;
1266 bstp_timer_start(&bp->bp_recent_root_timer,
1271 bp->bp_role = role;
1273 bp->bp_proposing = 0;
1277 switch (bp->bp_role) {
1282 bp->bp_ifp->if_xname);
1283 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1284 bstp_timer_stop(&bp->bp_recent_root_timer);
1285 bstp_timer_latch(&bp->bp_forward_delay_timer);
1286 bp->bp_sync = 0;
1287 bp->bp_synced = 1;
1288 bp->bp_reroot = 0;
1293 bp->bp_ifp->if_xname);
1294 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1295 bstp_timer_latch(&bp->bp_recent_root_timer);
1296 bp->bp_proposing = 0;
1301 bp->bp_ifp->if_xname);
1302 bstp_timer_start(&bp->bp_hello_timer,
1303 bp->bp_desg_htime);
1304 bp->bp_agree = 0;
1309 bstp_update_tc(bp);
1313 bstp_set_port_proto(struct bstp_port *bp, int proto)
1315 struct bstp_state *bs = bp->bp_bs;
1321 bstp_timer_stop(&bp->bp_migrate_delay_timer);
1323 bp->bp_operedge = 0;
1325 if (bp->bp_path_cost > 65535)
1326 bp->bp_path_cost = 65535;
1330 bstp_timer_start(&bp->bp_migrate_delay_timer,
1339 bp->bp_protover = proto;
1340 bp->bp_flags &= ~BSTP_PORT_CANMIGRATE;
1344 bstp_set_port_tc(struct bstp_port *bp, int state)
1346 struct bstp_state *bs = bp->bp_bs;
1348 bp->bp_tcstate = state;
1351 switch (bp->bp_tcstate) {
1353 DPRINTF("%s -> TC_ACTIVE\n", bp->bp_ifp->if_xname);
1358 bstp_timer_stop(&bp->bp_tc_timer);
1360 bp->bp_fdbflush = 1;
1361 taskqueue_enqueue(taskqueue_swi, &bp->bp_rtagetask);
1362 bp->bp_tc_ack = 0;
1363 DPRINTF("%s -> TC_INACTIVE\n", bp->bp_ifp->if_xname);
1367 bp->bp_rcvdtc = 0;
1368 bp->bp_rcvdtcn = 0;
1369 bp->bp_rcvdtca = 0;
1370 bp->bp_tc_prop = 0;
1371 DPRINTF("%s -> TC_LEARNING\n", bp->bp_ifp->if_xname);
1375 bstp_set_timer_tc(bp);
1376 bstp_set_other_tcprop(bp);
1378 bp->bp_flags |= BSTP_PORT_NEWINFO;
1379 bstp_transmit(bs, bp);
1381 DPRINTF("%s -> TC_DETECTED\n", bp->bp_ifp->if_xname);
1382 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1386 bstp_set_timer_tc(bp);
1387 DPRINTF("%s -> TC_TCN\n", bp->bp_ifp->if_xname);
1390 bp->bp_rcvdtc = 0;
1391 bp->bp_rcvdtcn = 0;
1392 if (bp->bp_role == BSTP_ROLE_DESIGNATED)
1393 bp->bp_tc_ack = 1;
1395 bstp_set_other_tcprop(bp);
1396 DPRINTF("%s -> TC_TC\n", bp->bp_ifp->if_xname);
1397 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1402 bp->bp_fdbflush = 1;
1403 taskqueue_enqueue(taskqueue_swi, &bp->bp_rtagetask);
1404 bp->bp_tc_prop = 0;
1405 bstp_set_timer_tc(bp);
1406 DPRINTF("%s -> TC_PROPAG\n", bp->bp_ifp->if_xname);
1407 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1411 bstp_timer_stop(&bp->bp_tc_timer);
1412 bp->bp_rcvdtca = 0;
1413 DPRINTF("%s -> TC_ACK\n", bp->bp_ifp->if_xname);
1414 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1420 bstp_set_timer_tc(struct bstp_port *bp)
1422 struct bstp_state *bs = bp->bp_bs;
1424 if (bp->bp_tc_timer.active)
1427 switch (bp->bp_protover) {
1429 bstp_timer_start(&bp->bp_tc_timer,
1430 bp->bp_desg_htime + BSTP_TICK_VAL);
1431 bp->bp_flags |= BSTP_PORT_NEWINFO;
1435 bstp_timer_start(&bp->bp_tc_timer,
1442 bstp_set_timer_msgage(struct bstp_port *bp)
1444 if (bp->bp_port_msg_age + BSTP_MESSAGE_AGE_INCR <=
1445 bp->bp_port_max_age) {
1446 bstp_timer_start(&bp->bp_message_age_timer,
1447 bp->bp_port_htime * 3);
1450 bstp_timer_start(&bp->bp_message_age_timer, 0);
1454 bstp_rerooted(struct bstp_state *bs, struct bstp_port *bp)
1460 if (bp2 == bp)
1525 struct bstp_port *bp;
1533 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
1534 bp->bp_txcount = 0;
1542 struct bstp_port *bp;
1557 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1559 bp->bp_infois = BSTP_INFO_DISABLED;
1560 bp->bp_txcount = 0;
1561 bstp_set_port_proto(bp, bs->bs_protover);
1562 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
1563 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
1564 bstp_timer_stop(&bp->bp_recent_backup_timer);
1588 bstp_set_port_priority(struct bstp_port *bp, int pri)
1590 struct bstp_state *bs = bp->bp_bs;
1599 bp->bp_priority = pri;
1606 bstp_set_path_cost(struct bstp_port *bp, uint32_t path_cost)
1608 struct bstp_state *bs = bp->bp_bs;
1614 if (bp->bp_protover == BSTP_PROTO_STP && path_cost > 65535)
1620 bp->bp_flags &= ~BSTP_PORT_ADMCOST;
1621 bp->bp_path_cost = bstp_calc_path_cost(bp);
1623 bp->bp_path_cost = path_cost;
1624 bp->bp_flags |= BSTP_PORT_ADMCOST;
1632 bstp_set_edge(struct bstp_port *bp, int set)
1634 struct bstp_state *bs = bp->bp_bs;
1637 if ((bp->bp_operedge = set) == 0)
1638 bp->bp_flags &= ~BSTP_PORT_ADMEDGE;
1640 bp->bp_flags |= BSTP_PORT_ADMEDGE;
1646 bstp_set_autoedge(struct bstp_port *bp, int set)
1648 struct bstp_state *bs = bp->bp_bs;
1652 bp->bp_flags |= BSTP_PORT_AUTOEDGE;
1654 if (bp->bp_edge_delay_timer.active == 0)
1655 bstp_edge_delay_expiry(bs, bp);
1657 bp->bp_flags &= ~BSTP_PORT_AUTOEDGE;
1663 bstp_set_ptp(struct bstp_port *bp, int set)
1665 struct bstp_state *bs = bp->bp_bs;
1668 bp->bp_ptp_link = set;
1674 bstp_set_autoptp(struct bstp_port *bp, int set)
1676 struct bstp_state *bs = bp->bp_bs;
1680 bp->bp_flags |= BSTP_PORT_AUTOPTP;
1681 if (bp->bp_role != BSTP_ROLE_DISABLED)
1682 taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
1684 bp->bp_flags &= ~BSTP_PORT_AUTOPTP;
1693 bstp_calc_path_cost(struct bstp_port *bp)
1695 struct ifnet *ifp = bp->bp_ifp;
1699 if (bp->bp_flags & BSTP_PORT_ADMCOST)
1700 return bp->bp_path_cost;
1704 bp->bp_flags |= BSTP_PORT_PNDCOST;
1718 if (bp->bp_protover == BSTP_PROTO_STP && path_cost > 65535)
1731 struct bstp_port *bp = (struct bstp_port *)arg;
1732 struct bstp_state *bs = bp->bp_bs;
1734 if (bp->bp_active == 1 && bs->bs_state_cb != NULL)
1735 (*bs->bs_state_cb)(bp->bp_ifp, bp->bp_state);
1745 struct bstp_port *bp = (struct bstp_port *)arg;
1746 struct bstp_state *bs = bp->bp_bs;
1750 switch (bp->bp_protover) {
1753 age = bp->bp_desg_fdelay / BSTP_TICK_VAL;
1762 if (bp->bp_active == 1 && bs->bs_rtage_cb != NULL)
1763 (*bs->bs_rtage_cb)(bp->bp_ifp, age);
1767 bp->bp_fdbflush = 0;
1772 bstp_linkstate(struct bstp_port *bp)
1774 struct bstp_state *bs = bp->bp_bs;
1776 if (!bp->bp_active)
1779 bstp_ifupdstatus(bp, 0);
1781 bstp_update_state(bs, bp);
1788 struct bstp_port *bp = (struct bstp_port *)arg;
1789 struct bstp_state *bs = bp->bp_bs;
1790 struct ifnet *ifp = bp->bp_ifp;
1794 if (!bp->bp_active)
1805 if (bp->bp_flags & BSTP_PORT_AUTOPTP) {
1809 if (bp->bp_ptp_link ^ fdx) {
1810 bp->bp_ptp_link = fdx;
1816 if (bp->bp_flags & BSTP_PORT_PNDCOST) {
1819 cost = bstp_calc_path_cost(bp);
1820 if (bp->bp_path_cost != cost) {
1821 bp->bp_path_cost = cost;
1824 bp->bp_flags &= ~BSTP_PORT_PNDCOST;
1827 if (bp->bp_role == BSTP_ROLE_DISABLED) {
1828 bstp_enable_port(bs, bp);
1832 if (bp->bp_role != BSTP_ROLE_DISABLED) {
1833 bstp_disable_port(bs, bp);
1835 if ((bp->bp_flags & BSTP_PORT_ADMEDGE) &&
1836 bp->bp_protover == BSTP_PROTO_RSTP)
1837 bp->bp_operedge = 1;
1840 } else if (bp->bp_infois != BSTP_INFO_DISABLED) {
1841 bstp_disable_port(bs, bp);
1850 bstp_enable_port(struct bstp_state *bs, struct bstp_port *bp)
1852 bp->bp_infois = BSTP_INFO_AGED;
1856 bstp_disable_port(struct bstp_state *bs, struct bstp_port *bp)
1858 bp->bp_infois = BSTP_INFO_DISABLED;
1865 struct bstp_port *bp;
1876 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1877 if (!(bp->bp_ifp->if_capabilities & IFCAP_LINKSTATE))
1878 taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
1883 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1885 bstp_timer_dectest(&bp->bp_tc_timer);
1886 bstp_timer_dectest(&bp->bp_recent_root_timer);
1887 bstp_timer_dectest(&bp->bp_forward_delay_timer);
1888 bstp_timer_dectest(&bp->bp_recent_backup_timer);
1890 if (bstp_timer_dectest(&bp->bp_hello_timer))
1891 bstp_hello_timer_expiry(bs, bp);
1893 if (bstp_timer_dectest(&bp->bp_message_age_timer))
1894 bstp_message_age_expiry(bs, bp);
1896 if (bstp_timer_dectest(&bp->bp_migrate_delay_timer))
1897 bstp_migrate_delay_expiry(bs, bp);
1899 if (bstp_timer_dectest(&bp->bp_edge_delay_timer))
1900 bstp_edge_delay_expiry(bs, bp);
1903 bstp_update_state(bs, bp);
1905 if (bp->bp_txcount > 0)
1906 bp->bp_txcount--;
1951 bstp_hello_timer_expiry(struct bstp_state *bs, struct bstp_port *bp)
1953 if ((bp->bp_flags & BSTP_PORT_NEWINFO) ||
1954 bp->bp_role == BSTP_ROLE_DESIGNATED ||
1955 (bp->bp_role == BSTP_ROLE_ROOT &&
1956 bp->bp_tc_timer.active == 1)) {
1957 bstp_timer_start(&bp->bp_hello_timer, bp->bp_desg_htime);
1958 bp->bp_flags |= BSTP_PORT_NEWINFO;
1959 bstp_transmit(bs, bp);
1964 bstp_message_age_expiry(struct bstp_state *bs, struct bstp_port *bp)
1966 if (bp->bp_infois == BSTP_INFO_RECEIVED) {
1967 bp->bp_infois = BSTP_INFO_AGED;
1969 DPRINTF("aged info on %s\n", bp->bp_ifp->if_xname);
1974 bstp_migrate_delay_expiry(struct bstp_state *bs, struct bstp_port *bp)
1976 bp->bp_flags |= BSTP_PORT_CANMIGRATE;
1980 bstp_edge_delay_expiry(struct bstp_state *bs, struct bstp_port *bp)
1982 if ((bp->bp_flags & BSTP_PORT_AUTOEDGE) &&
1983 bp->bp_protover == BSTP_PROTO_RSTP && bp->bp_proposing &&
1984 bp->bp_role == BSTP_ROLE_DESIGNATED) {
1985 bp->bp_operedge = 1;
1986 DPRINTF("%s -> edge port\n", bp->bp_ifp->if_xname);
2023 struct bstp_port *bp;
2085 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
2086 bp->bp_port_id = (bp->bp_priority << 8) |
2087 (bp->bp_ifp->if_index & 0xfff);
2088 taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
2102 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
2103 bp->bp_infois = BSTP_INFO_DISABLED;
2104 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
2186 struct bstp_port *bp;
2190 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
2191 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
2199 bstp_create(struct bstp_state *bs, struct bstp_port *bp, struct ifnet *ifp)
2201 bzero(bp, sizeof(struct bstp_port));
2204 bp->bp_ifp = ifp;
2205 bp->bp_bs = bs;
2206 bp->bp_priority = BSTP_DEFAULT_PORT_PRIORITY;
2207 TASK_INIT(&bp->bp_statetask, 0, bstp_notify_state, bp);
2208 TASK_INIT(&bp->bp_rtagetask, 0, bstp_notify_rtage, bp);
2209 TASK_INIT(&bp->bp_mediatask, 0, bstp_ifupdstatus, bp);
2212 bp->bp_infois = BSTP_INFO_DISABLED;
2213 bp->bp_flags = BSTP_PORT_AUTOEDGE|BSTP_PORT_AUTOPTP;
2214 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
2215 bstp_set_port_proto(bp, bs->bs_protover);
2216 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
2217 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
2218 bp->bp_path_cost = bstp_calc_path_cost(bp);
2224 bstp_enable(struct bstp_port *bp)
2226 struct bstp_state *bs = bp->bp_bs;
2227 struct ifnet *ifp = bp->bp_ifp;
2229 KASSERT(bp->bp_active == 0, ("already a bstp member"));
2240 LIST_INSERT_HEAD(&bs->bs_bplist, bp, bp_next);
2241 bp->bp_active = 1;
2242 bp->bp_flags |= BSTP_PORT_NEWINFO;
2244 bstp_update_roles(bs, bp);
2250 bstp_disable(struct bstp_port *bp)
2252 struct bstp_state *bs = bp->bp_bs;
2254 KASSERT(bp->bp_active == 1, ("not a bstp member"));
2257 bstp_disable_port(bs, bp);
2258 LIST_REMOVE(bp, bp_next);
2259 bp->bp_active = 0;
2268 bstp_destroy(struct bstp_port *bp)
2270 KASSERT(bp->bp_active == 0, ("port is still attached"));
2271 taskqueue_drain(taskqueue_swi, &bp->bp_statetask);
2272 taskqueue_drain(taskqueue_swi, &bp->bp_rtagetask);
2273 taskqueue_drain(taskqueue_swi, &bp->bp_mediatask);
2275 if (bp->bp_bs->bs_root_port == bp)
2276 bstp_assign_roles(bp->bp_bs);