Lines Matching refs:bp

151 bstp_transmit(struct bstp_state *bs, struct bstp_port *bp)
160 if (bp->bp_hello_timer.active == 0) {
162 bstp_hello_timer_expiry(bs, bp);
165 if (bp->bp_txcount > bs->bs_txholdcount)
169 if (bp->bp_protover == BSTP_PROTO_RSTP) {
170 bstp_transmit_bpdu(bs, bp);
171 bp->bp_tc_ack = 0;
173 switch (bp->bp_role) {
175 bstp_transmit_bpdu(bs, bp);
176 bp->bp_tc_ack = 0;
180 bstp_transmit_tcn(bs, bp);
184 bstp_timer_start(&bp->bp_hello_timer, bp->bp_desg_htime);
185 bp->bp_flags &= ~BSTP_PORT_NEWINFO;
189 bstp_transmit_bpdu(struct bstp_state *bs, struct bstp_port *bp)
195 bpdu.cbu_rootpri = htons(bp->bp_desg_pv.pv_root_id >> 48);
196 PV2ADDR(bp->bp_desg_pv.pv_root_id, bpdu.cbu_rootaddr);
198 bpdu.cbu_rootpathcost = htonl(bp->bp_desg_pv.pv_cost);
200 bpdu.cbu_bridgepri = htons(bp->bp_desg_pv.pv_dbridge_id >> 48);
201 PV2ADDR(bp->bp_desg_pv.pv_dbridge_id, bpdu.cbu_bridgeaddr);
203 bpdu.cbu_portid = htons(bp->bp_port_id);
204 bpdu.cbu_messageage = htons(bp->bp_desg_msg_age);
205 bpdu.cbu_maxage = htons(bp->bp_desg_max_age);
206 bpdu.cbu_hellotime = htons(bp->bp_desg_htime);
207 bpdu.cbu_forwarddelay = htons(bp->bp_desg_fdelay);
209 bpdu.cbu_flags = bstp_pdu_flags(bp);
211 switch (bp->bp_protover) {
221 bstp_send_bpdu(bs, bp, &bpdu);
225 bstp_transmit_tcn(struct bstp_state *bs, struct bstp_port *bp)
228 struct ifnet *ifp = bp->bp_ifp;
232 KASSERT(bp == bs->bs_root_port, ("%s: bad root port\n", __func__));
259 bp->bp_txcount++;
264 bstp_decode_bpdu(struct bstp_port *bp, struct bstp_cbpdu *cpdu,
293 cu->cu_pv.pv_port_id = bp->bp_port_id;
337 bstp_send_bpdu(struct bstp_state *bs, struct bstp_port *bp,
346 ifp = bp->bp_ifp;
388 bp->bp_txcount++;
393 bstp_pdu_flags(struct bstp_port *bp)
397 if (bp->bp_proposing && bp->bp_state != BSTP_IFSTATE_FORWARDING)
400 if (bp->bp_agree)
403 if (bp->bp_tc_timer.active)
406 if (bp->bp_tc_ack)
409 switch (bp->bp_state) {
419 switch (bp->bp_role) {
438 switch (bp->bp_protover) {
450 bstp_input(struct bstp_port *bp, struct ifnet *ifp, struct mbuf *m)
452 struct bstp_state *bs = bp->bp_bs;
457 if (bp->bp_active == 0) {
495 if (tpdu.tbu_protover != bp->bp_protover) {
500 if (bp->bp_flags & BSTP_PORT_CANMIGRATE)
501 bstp_set_port_proto(bp, tpdu.tbu_protover);
507 bp->bp_operedge = 0;
508 bstp_timer_start(&bp->bp_edge_delay_timer,
513 bstp_received_stp(bs, bp, &m, &tpdu);
517 bstp_received_rstp(bs, bp, &m, &tpdu);
527 bstp_received_stp(struct bstp_state *bs, struct bstp_port *bp,
531 struct bstp_config_unit *cu = &bp->bp_msg_cu;
537 bstp_received_tcn(bs, bp, &tu);
545 bstp_decode_bpdu(bp, &cpdu, cu);
546 bstp_received_bpdu(bs, bp, cu);
552 bstp_received_rstp(struct bstp_state *bs, struct bstp_port *bp,
556 struct bstp_config_unit *cu = &bp->bp_msg_cu;
566 bstp_decode_bpdu(bp, &cpdu, cu);
567 bstp_received_bpdu(bs, bp, cu);
571 bstp_received_tcn(struct bstp_state *bs, struct bstp_port *bp,
574 bp->bp_rcvdtcn = 1;
575 bstp_update_tc(bp);
579 bstp_received_bpdu(struct bstp_state *bs, struct bstp_port *bp,
587 switch (bp->bp_infois) {
593 type = bstp_pdu_rcvtype(bp, cu);
598 bp->bp_agreed = 0;
599 bp->bp_proposing = 0;
602 bp->bp_proposed = 1;
604 bp->bp_rcvdtc = 1;
606 bp->bp_rcvdtca = 1;
608 if (bp->bp_agree &&
609 !bstp_pdu_bettersame(bp, BSTP_INFO_RECEIVED))
610 bp->bp_agree = 0;
613 bp->bp_port_pv = cu->cu_pv;
614 bp->bp_port_msg_age = cu->cu_message_age;
615 bp->bp_port_max_age = cu->cu_max_age;
616 bp->bp_port_fdelay = cu->cu_forward_delay;
617 bp->bp_port_htime =
622 bstp_set_timer_msgage(bp);
624 bp->bp_infois = BSTP_INFO_RECEIVED;
630 bp->bp_proposed = 1;
632 bp->bp_rcvdtc = 1;
634 bp->bp_rcvdtca = 1;
637 bstp_set_timer_msgage(bp);
642 bp->bp_agreed = 1;
643 bp->bp_proposing = 0;
652 if (cu->cu_agree && bp->bp_ptp_link) {
653 bp->bp_agreed = 1;
654 bp->bp_proposing = 0;
656 bp->bp_agreed = 0;
659 bp->bp_rcvdtc = 1;
661 bp->bp_rcvdtca = 1;
668 bstp_update_state(bs, bp);
672 bstp_pdu_rcvtype(struct bstp_port *bp, struct bstp_config_unit *cu)
681 if (bstp_info_superior(&bp->bp_port_pv, &cu->cu_pv))
684 else if (bstp_info_cmp(&bp->bp_port_pv, &cu->cu_pv) ==
686 if (bp->bp_port_msg_age != cu->cu_message_age ||
687 bp->bp_port_max_age != cu->cu_max_age ||
688 bp->bp_port_fdelay != cu->cu_forward_delay ||
689 bp->bp_port_htime != cu->cu_hello_time)
704 if (bstp_info_cmp(&bp->bp_port_pv, &cu->cu_pv) <= INFO_SAME)
717 bstp_pdu_bettersame(struct bstp_port *bp, int newinfo)
720 bp->bp_infois == BSTP_INFO_RECEIVED &&
721 bstp_info_cmp(&bp->bp_port_pv, &bp->bp_msg_cu.cu_pv) >= INFO_SAME)
725 bp->bp_infois == BSTP_INFO_MINE &&
726 bstp_info_cmp(&bp->bp_port_pv, &bp->bp_desg_pv) >= INFO_SAME)
779 struct bstp_port *bp, *rbp = NULL;
791 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
792 if (bp->bp_infois != BSTP_INFO_RECEIVED)
795 pv = bp->bp_port_pv;
796 pv.pv_cost += bp->bp_path_cost;
808 bs->bs_root_msg_age = bp->bp_port_msg_age +
810 bs->bs_root_max_age = bp->bp_port_max_age;
811 bs->bs_root_fdelay = bp->bp_port_fdelay;
812 bs->bs_root_htime = bp->bp_port_htime;
813 rbp = bp;
817 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
819 bp->bp_desg_pv.pv_root_id = bs->bs_root_pv.pv_root_id;
820 bp->bp_desg_pv.pv_cost = bs->bs_root_pv.pv_cost;
821 bp->bp_desg_pv.pv_dbridge_id = bs->bs_bridge_pv.pv_dbridge_id;
822 bp->bp_desg_pv.pv_dport_id = bp->bp_port_id;
823 bp->bp_desg_pv.pv_port_id = bp->bp_port_id;
826 bp->bp_desg_msg_age = bs->bs_root_msg_age;
827 bp->bp_desg_max_age = bs->bs_root_max_age;
828 bp->bp_desg_fdelay = bs->bs_root_fdelay;
829 bp->bp_desg_htime = bs->bs_bridge_htime;
832 switch (bp->bp_infois) {
834 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
838 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
839 bstp_update_info(bp);
843 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
845 if (bstp_info_cmp(&bp->bp_port_pv,
846 &bp->bp_desg_pv) != INFO_SAME ||
848 (bp->bp_port_msg_age != rbp->bp_port_msg_age ||
849 bp->bp_port_max_age != rbp->bp_port_max_age ||
850 bp->bp_port_fdelay != rbp->bp_port_fdelay ||
851 bp->bp_port_htime != rbp->bp_port_htime)))
852 bstp_update_info(bp);
856 if (bp == rbp) {
861 bstp_set_port_role(bp, BSTP_ROLE_ROOT);
862 bs->bs_root_port = bp;
863 } else if (bstp_info_cmp(&bp->bp_port_pv,
864 &bp->bp_desg_pv) == INFO_BETTER) {
869 bstp_set_port_role(bp, BSTP_ROLE_DESIGNATED);
870 bstp_update_info(bp);
873 bp->bp_port_pv.pv_dbridge_id,
879 bstp_set_port_role(bp,
886 bstp_set_port_role(bp,
896 bstp_update_state(struct bstp_state *bs, struct bstp_port *bp)
916 bstp_update_roles(bs, bp);
917 bstp_update_tc(bp);
921 bstp_update_roles(struct bstp_state *bs, struct bstp_port *bp)
923 switch (bp->bp_role) {
926 if (bp->bp_sync || !bp->bp_synced || bp->bp_reroot) {
927 bp->bp_sync = 0;
928 bp->bp_synced = 1;
929 bp->bp_reroot = 0;
935 if ((bs->bs_allsynced && !bp->bp_agree) ||
936 (bp->bp_proposed && bp->bp_agree)) {
937 bp->bp_proposed = 0;
938 bp->bp_agree = 1;
939 bp->bp_flags |= BSTP_PORT_NEWINFO;
941 bp->bp_ifp->if_xname);
944 if (bp->bp_proposed && !bp->bp_agree) {
946 bp->bp_proposed = 0;
948 bp->bp_ifp->if_xname);
952 if (bp->bp_sync || !bp->bp_synced || bp->bp_reroot) {
953 bp->bp_sync = 0;
954 bp->bp_synced = 1;
955 bp->bp_reroot = 0;
956 DPRINTF("%s -> ALTERNATE_PORT\n", bp->bp_ifp->if_xname);
961 if (bp->bp_state != BSTP_IFSTATE_FORWARDING && !bp->bp_reroot) {
963 DPRINTF("%s -> ROOT_REROOT\n", bp->bp_ifp->if_xname);
966 if ((bs->bs_allsynced && !bp->bp_agree) ||
967 (bp->bp_proposed && bp->bp_agree)) {
968 bp->bp_proposed = 0;
969 bp->bp_sync = 0;
970 bp->bp_agree = 1;
971 bp->bp_flags |= BSTP_PORT_NEWINFO;
972 DPRINTF("%s -> ROOT_AGREED\n", bp->bp_ifp->if_xname);
975 if (bp->bp_proposed && !bp->bp_agree) {
977 bp->bp_proposed = 0;
978 DPRINTF("%s -> ROOT_PROPOSED\n", bp->bp_ifp->if_xname);
981 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
982 (bp->bp_forward_delay_timer.active == 0 ||
983 (bstp_rerooted(bs, bp) &&
984 bp->bp_recent_backup_timer.active == 0 &&
985 bp->bp_protover == BSTP_PROTO_RSTP))) {
986 switch (bp->bp_state) {
988 bstp_set_port_state(bp, BSTP_IFSTATE_LEARNING);
991 bstp_set_port_state(bp,
997 if (bp->bp_state == BSTP_IFSTATE_FORWARDING && bp->bp_reroot) {
998 bp->bp_reroot = 0;
999 DPRINTF("%s -> ROOT_REROOTED\n", bp->bp_ifp->if_xname);
1004 if (bp->bp_recent_root_timer.active == 0 && bp->bp_reroot) {
1005 bp->bp_reroot = 0;
1007 bp->bp_ifp->if_xname);
1010 if ((bp->bp_state == BSTP_IFSTATE_DISCARDING &&
1011 !bp->bp_synced) || (bp->bp_agreed && !bp->bp_synced) ||
1012 (bp->bp_operedge && !bp->bp_synced) ||
1013 (bp->bp_sync && bp->bp_synced)) {
1014 bstp_timer_stop(&bp->bp_recent_root_timer);
1015 bp->bp_synced = 1;
1016 bp->bp_sync = 0;
1018 bp->bp_ifp->if_xname);
1021 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
1022 !bp->bp_agreed && !bp->bp_proposing &&
1023 !bp->bp_operedge) {
1024 bp->bp_proposing = 1;
1025 bp->bp_flags |= BSTP_PORT_NEWINFO;
1026 bstp_timer_start(&bp->bp_edge_delay_timer,
1027 (bp->bp_ptp_link ? BSTP_DEFAULT_MIGRATE_DELAY :
1028 bp->bp_desg_max_age));
1030 bp->bp_ifp->if_xname);
1033 if (bp->bp_state != BSTP_IFSTATE_FORWARDING &&
1034 (bp->bp_forward_delay_timer.active == 0 || bp->bp_agreed ||
1035 bp->bp_operedge) &&
1036 (bp->bp_recent_root_timer.active == 0 || !bp->bp_reroot) &&
1037 !bp->bp_sync) {
1038 if (bp->bp_agreed)
1039 DPRINTF("%s -> AGREED\n", bp->bp_ifp->if_xname);
1044 if (bp->bp_agreed || bp->bp_operedge ||
1045 bp->bp_state == BSTP_IFSTATE_LEARNING) {
1046 bstp_set_port_state(bp,
1048 bp->bp_agreed = bp->bp_protover;
1049 } else if (bp->bp_state == BSTP_IFSTATE_DISCARDING)
1050 bstp_set_port_state(bp, BSTP_IFSTATE_LEARNING);
1053 if (((bp->bp_sync && !bp->bp_synced) ||
1054 (bp->bp_reroot && bp->bp_recent_root_timer.active) ||
1055 (bp->bp_flags & BSTP_PORT_DISPUTED)) && !bp->bp_operedge &&
1056 bp->bp_state != BSTP_IFSTATE_DISCARDING) {
1057 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1058 bp->bp_flags &= ~BSTP_PORT_DISPUTED;
1059 bstp_timer_start(&bp->bp_forward_delay_timer,
1060 bp->bp_protover == BSTP_PROTO_RSTP ?
1061 bp->bp_desg_htime : bp->bp_desg_fdelay);
1063 bp->bp_ifp->if_xname);
1068 if (bp->bp_flags & BSTP_PORT_NEWINFO)
1069 bstp_transmit(bs, bp);
1073 bstp_update_tc(struct bstp_port *bp)
1075 switch (bp->bp_tcstate) {
1077 if ((bp->bp_role != BSTP_ROLE_DESIGNATED &&
1078 bp->bp_role != BSTP_ROLE_ROOT) || bp->bp_operedge)
1079 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1081 if (bp->bp_rcvdtcn)
1082 bstp_set_port_tc(bp, BSTP_TCSTATE_TCN);
1083 if (bp->bp_rcvdtc)
1084 bstp_set_port_tc(bp, BSTP_TCSTATE_TC);
1086 if (bp->bp_tc_prop && !bp->bp_operedge)
1087 bstp_set_port_tc(bp, BSTP_TCSTATE_PROPAG);
1089 if (bp->bp_rcvdtca)
1090 bstp_set_port_tc(bp, BSTP_TCSTATE_ACK);
1094 if ((bp->bp_state == BSTP_IFSTATE_LEARNING ||
1095 bp->bp_state == BSTP_IFSTATE_FORWARDING) &&
1096 bp->bp_fdbflush == 0)
1097 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1101 if (bp->bp_rcvdtc || bp->bp_rcvdtcn || bp->bp_rcvdtca ||
1102 bp->bp_tc_prop)
1103 bstp_set_port_tc(bp, BSTP_TCSTATE_LEARNING);
1104 else if (bp->bp_role != BSTP_ROLE_DESIGNATED &&
1105 bp->bp_role != BSTP_ROLE_ROOT &&
1106 bp->bp_state == BSTP_IFSTATE_DISCARDING)
1107 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
1109 if ((bp->bp_role == BSTP_ROLE_DESIGNATED ||
1110 bp->bp_role == BSTP_ROLE_ROOT) &&
1111 bp->bp_state == BSTP_IFSTATE_FORWARDING &&
1112 !bp->bp_operedge)
1113 bstp_set_port_tc(bp, BSTP_TCSTATE_DETECTED);
1123 bp->bp_ifp->if_xname);
1130 bstp_update_info(struct bstp_port *bp)
1132 struct bstp_state *bs = bp->bp_bs;
1134 bp->bp_proposing = 0;
1135 bp->bp_proposed = 0;
1137 if (bp->bp_agreed && !bstp_pdu_bettersame(bp, BSTP_INFO_MINE))
1138 bp->bp_agreed = 0;
1140 if (bp->bp_synced && !bp->bp_agreed) {
1141 bp->bp_synced = 0;
1146 bp->bp_port_pv = bp->bp_desg_pv;
1147 bp->bp_port_msg_age = bp->bp_desg_msg_age;
1148 bp->bp_port_max_age = bp->bp_desg_max_age;
1149 bp->bp_port_fdelay = bp->bp_desg_fdelay;
1150 bp->bp_port_htime = bp->bp_desg_htime;
1151 bp->bp_infois = BSTP_INFO_MINE;
1154 bp->bp_flags |= BSTP_PORT_NEWINFO;
1159 bstp_set_other_tcprop(struct bstp_port *bp)
1161 struct bstp_state *bs = bp->bp_bs;
1167 if (bp2 == bp)
1176 struct bstp_port *bp;
1180 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
1181 bp->bp_reroot = 1;
1187 struct bstp_port *bp;
1191 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1192 bp->bp_sync = 1;
1193 bp->bp_synced = 0; /* Not explicit in spec */
1200 bstp_set_port_state(struct bstp_port *bp, int state)
1202 if (bp->bp_state == state)
1205 bp->bp_state = state;
1207 switch (bp->bp_state) {
1210 bp->bp_ifp->if_xname);
1215 bp->bp_ifp->if_xname);
1217 bstp_timer_start(&bp->bp_forward_delay_timer,
1218 bp->bp_protover == BSTP_PROTO_RSTP ?
1219 bp->bp_desg_htime : bp->bp_desg_fdelay);
1224 bp->bp_ifp->if_xname);
1226 bstp_timer_stop(&bp->bp_forward_delay_timer);
1228 bp->bp_forward_transitions++;
1233 taskqueue_enqueue(taskqueue_swi, &bp->bp_statetask);
1237 bstp_set_port_role(struct bstp_port *bp, int role)
1239 struct bstp_state *bs = bp->bp_bs;
1241 if (bp->bp_role == role)
1245 switch (bp->bp_role) {
1247 bstp_timer_start(&bp->bp_forward_delay_timer,
1248 bp->bp_desg_max_age);
1252 bstp_timer_start(&bp->bp_recent_backup_timer,
1253 bp->bp_desg_htime * 2);
1256 bstp_timer_start(&bp->bp_forward_delay_timer,
1257 bp->bp_desg_fdelay);
1258 bp->bp_sync = 0;
1259 bp->bp_synced = 1;
1260 bp->bp_reroot = 0;
1264 bstp_timer_start(&bp->bp_recent_root_timer,
1269 bp->bp_role = role;
1271 bp->bp_proposing = 0;
1275 switch (bp->bp_role) {
1280 bp->bp_ifp->if_xname);
1281 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1282 bstp_timer_stop(&bp->bp_recent_root_timer);
1283 bstp_timer_latch(&bp->bp_forward_delay_timer);
1284 bp->bp_sync = 0;
1285 bp->bp_synced = 1;
1286 bp->bp_reroot = 0;
1291 bp->bp_ifp->if_xname);
1292 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
1293 bstp_timer_latch(&bp->bp_recent_root_timer);
1294 bp->bp_proposing = 0;
1299 bp->bp_ifp->if_xname);
1300 bstp_timer_start(&bp->bp_hello_timer,
1301 bp->bp_desg_htime);
1302 bp->bp_agree = 0;
1307 bstp_update_tc(bp);
1311 bstp_set_port_proto(struct bstp_port *bp, int proto)
1313 struct bstp_state *bs = bp->bp_bs;
1319 bstp_timer_stop(&bp->bp_migrate_delay_timer);
1321 bp->bp_operedge = 0;
1323 if (bp->bp_path_cost > 65535)
1324 bp->bp_path_cost = 65535;
1328 bstp_timer_start(&bp->bp_migrate_delay_timer,
1337 bp->bp_protover = proto;
1338 bp->bp_flags &= ~BSTP_PORT_CANMIGRATE;
1342 bstp_set_port_tc(struct bstp_port *bp, int state)
1344 struct bstp_state *bs = bp->bp_bs;
1346 bp->bp_tcstate = state;
1349 switch (bp->bp_tcstate) {
1351 DPRINTF("%s -> TC_ACTIVE\n", bp->bp_ifp->if_xname);
1356 bstp_timer_stop(&bp->bp_tc_timer);
1358 bp->bp_fdbflush = 1;
1359 taskqueue_enqueue(taskqueue_swi, &bp->bp_rtagetask);
1360 bp->bp_tc_ack = 0;
1361 DPRINTF("%s -> TC_INACTIVE\n", bp->bp_ifp->if_xname);
1365 bp->bp_rcvdtc = 0;
1366 bp->bp_rcvdtcn = 0;
1367 bp->bp_rcvdtca = 0;
1368 bp->bp_tc_prop = 0;
1369 DPRINTF("%s -> TC_LEARNING\n", bp->bp_ifp->if_xname);
1373 bstp_set_timer_tc(bp);
1374 bstp_set_other_tcprop(bp);
1376 bp->bp_flags |= BSTP_PORT_NEWINFO;
1377 bstp_transmit(bs, bp);
1379 DPRINTF("%s -> TC_DETECTED\n", bp->bp_ifp->if_xname);
1380 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1384 bstp_set_timer_tc(bp);
1385 DPRINTF("%s -> TC_TCN\n", bp->bp_ifp->if_xname);
1388 bp->bp_rcvdtc = 0;
1389 bp->bp_rcvdtcn = 0;
1390 if (bp->bp_role == BSTP_ROLE_DESIGNATED)
1391 bp->bp_tc_ack = 1;
1393 bstp_set_other_tcprop(bp);
1394 DPRINTF("%s -> TC_TC\n", bp->bp_ifp->if_xname);
1395 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1400 bp->bp_fdbflush = 1;
1401 taskqueue_enqueue(taskqueue_swi, &bp->bp_rtagetask);
1402 bp->bp_tc_prop = 0;
1403 bstp_set_timer_tc(bp);
1404 DPRINTF("%s -> TC_PROPAG\n", bp->bp_ifp->if_xname);
1405 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1409 bstp_timer_stop(&bp->bp_tc_timer);
1410 bp->bp_rcvdtca = 0;
1411 DPRINTF("%s -> TC_ACK\n", bp->bp_ifp->if_xname);
1412 bp->bp_tcstate = BSTP_TCSTATE_ACTIVE; /* UCT */
1418 bstp_set_timer_tc(struct bstp_port *bp)
1420 struct bstp_state *bs = bp->bp_bs;
1422 if (bp->bp_tc_timer.active)
1425 switch (bp->bp_protover) {
1427 bstp_timer_start(&bp->bp_tc_timer,
1428 bp->bp_desg_htime + BSTP_TICK_VAL);
1429 bp->bp_flags |= BSTP_PORT_NEWINFO;
1433 bstp_timer_start(&bp->bp_tc_timer,
1440 bstp_set_timer_msgage(struct bstp_port *bp)
1442 if (bp->bp_port_msg_age + BSTP_MESSAGE_AGE_INCR <=
1443 bp->bp_port_max_age) {
1444 bstp_timer_start(&bp->bp_message_age_timer,
1445 bp->bp_port_htime * 3);
1448 bstp_timer_start(&bp->bp_message_age_timer, 0);
1452 bstp_rerooted(struct bstp_state *bs, struct bstp_port *bp)
1458 if (bp2 == bp)
1523 struct bstp_port *bp;
1531 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
1532 bp->bp_txcount = 0;
1540 struct bstp_port *bp;
1555 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1557 bp->bp_infois = BSTP_INFO_DISABLED;
1558 bp->bp_txcount = 0;
1559 bstp_set_port_proto(bp, bs->bs_protover);
1560 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
1561 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
1562 bstp_timer_stop(&bp->bp_recent_backup_timer);
1586 bstp_set_port_priority(struct bstp_port *bp, int pri)
1588 struct bstp_state *bs = bp->bp_bs;
1597 bp->bp_priority = pri;
1604 bstp_set_path_cost(struct bstp_port *bp, uint32_t path_cost)
1606 struct bstp_state *bs = bp->bp_bs;
1612 if (bp->bp_protover == BSTP_PROTO_STP && path_cost > 65535)
1618 bp->bp_flags &= ~BSTP_PORT_ADMCOST;
1619 bp->bp_path_cost = bstp_calc_path_cost(bp);
1621 bp->bp_path_cost = path_cost;
1622 bp->bp_flags |= BSTP_PORT_ADMCOST;
1630 bstp_set_edge(struct bstp_port *bp, int set)
1632 struct bstp_state *bs = bp->bp_bs;
1635 if ((bp->bp_operedge = set) == 0)
1636 bp->bp_flags &= ~BSTP_PORT_ADMEDGE;
1638 bp->bp_flags |= BSTP_PORT_ADMEDGE;
1644 bstp_set_autoedge(struct bstp_port *bp, int set)
1646 struct bstp_state *bs = bp->bp_bs;
1650 bp->bp_flags |= BSTP_PORT_AUTOEDGE;
1652 if (bp->bp_edge_delay_timer.active == 0)
1653 bstp_edge_delay_expiry(bs, bp);
1655 bp->bp_flags &= ~BSTP_PORT_AUTOEDGE;
1661 bstp_set_ptp(struct bstp_port *bp, int set)
1663 struct bstp_state *bs = bp->bp_bs;
1666 bp->bp_ptp_link = set;
1672 bstp_set_autoptp(struct bstp_port *bp, int set)
1674 struct bstp_state *bs = bp->bp_bs;
1678 bp->bp_flags |= BSTP_PORT_AUTOPTP;
1679 if (bp->bp_role != BSTP_ROLE_DISABLED)
1680 taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
1682 bp->bp_flags &= ~BSTP_PORT_AUTOPTP;
1691 bstp_calc_path_cost(struct bstp_port *bp)
1693 struct ifnet *ifp = bp->bp_ifp;
1697 if (bp->bp_flags & BSTP_PORT_ADMCOST)
1698 return bp->bp_path_cost;
1702 bp->bp_flags |= BSTP_PORT_PNDCOST;
1716 if (bp->bp_protover == BSTP_PROTO_STP && path_cost > 65535)
1729 struct bstp_port *bp = (struct bstp_port *)arg;
1730 struct bstp_state *bs = bp->bp_bs;
1732 if (bp->bp_active == 1 && bs->bs_state_cb != NULL)
1733 (*bs->bs_state_cb)(bp->bp_ifp, bp->bp_state);
1743 struct bstp_port *bp = (struct bstp_port *)arg;
1744 struct bstp_state *bs = bp->bp_bs;
1748 switch (bp->bp_protover) {
1751 age = bp->bp_desg_fdelay / BSTP_TICK_VAL;
1760 if (bp->bp_active == 1 && bs->bs_rtage_cb != NULL)
1761 (*bs->bs_rtage_cb)(bp->bp_ifp, age);
1765 bp->bp_fdbflush = 0;
1770 bstp_linkstate(struct bstp_port *bp)
1772 struct bstp_state *bs = bp->bp_bs;
1774 if (!bp->bp_active)
1777 bstp_ifupdstatus(bp, 0);
1779 bstp_update_state(bs, bp);
1786 struct bstp_port *bp = (struct bstp_port *)arg;
1787 struct bstp_state *bs = bp->bp_bs;
1788 struct ifnet *ifp = bp->bp_ifp;
1792 if (!bp->bp_active)
1803 if (bp->bp_flags & BSTP_PORT_AUTOPTP) {
1807 if (bp->bp_ptp_link ^ fdx) {
1808 bp->bp_ptp_link = fdx;
1814 if (bp->bp_flags & BSTP_PORT_PNDCOST) {
1817 cost = bstp_calc_path_cost(bp);
1818 if (bp->bp_path_cost != cost) {
1819 bp->bp_path_cost = cost;
1822 bp->bp_flags &= ~BSTP_PORT_PNDCOST;
1825 if (bp->bp_role == BSTP_ROLE_DISABLED) {
1826 bstp_enable_port(bs, bp);
1830 if (bp->bp_role != BSTP_ROLE_DISABLED) {
1831 bstp_disable_port(bs, bp);
1833 if ((bp->bp_flags & BSTP_PORT_ADMEDGE) &&
1834 bp->bp_protover == BSTP_PROTO_RSTP)
1835 bp->bp_operedge = 1;
1838 } else if (bp->bp_infois != BSTP_INFO_DISABLED) {
1839 bstp_disable_port(bs, bp);
1848 bstp_enable_port(struct bstp_state *bs, struct bstp_port *bp)
1850 bp->bp_infois = BSTP_INFO_AGED;
1854 bstp_disable_port(struct bstp_state *bs, struct bstp_port *bp)
1856 bp->bp_infois = BSTP_INFO_DISABLED;
1863 struct bstp_port *bp;
1874 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1875 if (!(bp->bp_ifp->if_capabilities & IFCAP_LINKSTATE))
1876 taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
1881 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
1883 bstp_timer_dectest(&bp->bp_tc_timer);
1884 bstp_timer_dectest(&bp->bp_recent_root_timer);
1885 bstp_timer_dectest(&bp->bp_forward_delay_timer);
1886 bstp_timer_dectest(&bp->bp_recent_backup_timer);
1888 if (bstp_timer_dectest(&bp->bp_hello_timer))
1889 bstp_hello_timer_expiry(bs, bp);
1891 if (bstp_timer_dectest(&bp->bp_message_age_timer))
1892 bstp_message_age_expiry(bs, bp);
1894 if (bstp_timer_dectest(&bp->bp_migrate_delay_timer))
1895 bstp_migrate_delay_expiry(bs, bp);
1897 if (bstp_timer_dectest(&bp->bp_edge_delay_timer))
1898 bstp_edge_delay_expiry(bs, bp);
1901 bstp_update_state(bs, bp);
1903 if (bp->bp_txcount > 0)
1904 bp->bp_txcount--;
1949 bstp_hello_timer_expiry(struct bstp_state *bs, struct bstp_port *bp)
1951 if ((bp->bp_flags & BSTP_PORT_NEWINFO) ||
1952 bp->bp_role == BSTP_ROLE_DESIGNATED ||
1953 (bp->bp_role == BSTP_ROLE_ROOT &&
1954 bp->bp_tc_timer.active == 1)) {
1955 bstp_timer_start(&bp->bp_hello_timer, bp->bp_desg_htime);
1956 bp->bp_flags |= BSTP_PORT_NEWINFO;
1957 bstp_transmit(bs, bp);
1962 bstp_message_age_expiry(struct bstp_state *bs, struct bstp_port *bp)
1964 if (bp->bp_infois == BSTP_INFO_RECEIVED) {
1965 bp->bp_infois = BSTP_INFO_AGED;
1967 DPRINTF("aged info on %s\n", bp->bp_ifp->if_xname);
1972 bstp_migrate_delay_expiry(struct bstp_state *bs, struct bstp_port *bp)
1974 bp->bp_flags |= BSTP_PORT_CANMIGRATE;
1978 bstp_edge_delay_expiry(struct bstp_state *bs, struct bstp_port *bp)
1980 if ((bp->bp_flags & BSTP_PORT_AUTOEDGE) &&
1981 bp->bp_protover == BSTP_PROTO_RSTP && bp->bp_proposing &&
1982 bp->bp_role == BSTP_ROLE_DESIGNATED) {
1983 bp->bp_operedge = 1;
1984 DPRINTF("%s -> edge port\n", bp->bp_ifp->if_xname);
2021 struct bstp_port *bp;
2083 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
2084 bp->bp_port_id = (bp->bp_priority << 8) |
2085 (bp->bp_ifp->if_index & 0xfff);
2086 taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
2100 LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
2101 bp->bp_infois = BSTP_INFO_DISABLED;
2102 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
2184 struct bstp_port *bp;
2188 LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
2189 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
2197 bstp_create(struct bstp_state *bs, struct bstp_port *bp, struct ifnet *ifp)
2199 bzero(bp, sizeof(struct bstp_port));
2202 bp->bp_ifp = ifp;
2203 bp->bp_bs = bs;
2204 bp->bp_priority = BSTP_DEFAULT_PORT_PRIORITY;
2205 TASK_INIT(&bp->bp_statetask, 0, bstp_notify_state, bp);
2206 TASK_INIT(&bp->bp_rtagetask, 0, bstp_notify_rtage, bp);
2207 TASK_INIT(&bp->bp_mediatask, 0, bstp_ifupdstatus, bp);
2210 bp->bp_infois = BSTP_INFO_DISABLED;
2211 bp->bp_flags = BSTP_PORT_AUTOEDGE|BSTP_PORT_AUTOPTP;
2212 bstp_set_port_state(bp, BSTP_IFSTATE_DISCARDING);
2213 bstp_set_port_proto(bp, bs->bs_protover);
2214 bstp_set_port_role(bp, BSTP_ROLE_DISABLED);
2215 bstp_set_port_tc(bp, BSTP_TCSTATE_INACTIVE);
2216 bp->bp_path_cost = bstp_calc_path_cost(bp);
2222 bstp_enable(struct bstp_port *bp)
2224 struct bstp_state *bs = bp->bp_bs;
2225 struct ifnet *ifp = bp->bp_ifp;
2227 KASSERT(bp->bp_active == 0, ("already a bstp member"));
2238 LIST_INSERT_HEAD(&bs->bs_bplist, bp, bp_next);
2239 bp->bp_active = 1;
2240 bp->bp_flags |= BSTP_PORT_NEWINFO;
2242 bstp_update_roles(bs, bp);
2248 bstp_disable(struct bstp_port *bp)
2250 struct bstp_state *bs = bp->bp_bs;
2252 KASSERT(bp->bp_active == 1, ("not a bstp member"));
2255 bstp_disable_port(bs, bp);
2256 LIST_REMOVE(bp, bp_next);
2257 bp->bp_active = 0;
2266 bstp_destroy(struct bstp_port *bp)
2268 KASSERT(bp->bp_active == 0, ("port is still attached"));
2269 taskqueue_drain(taskqueue_swi, &bp->bp_statetask);
2270 taskqueue_drain(taskqueue_swi, &bp->bp_rtagetask);
2271 taskqueue_drain(taskqueue_swi, &bp->bp_mediatask);