Lines Matching +full:max +full:- +full:rt

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
123 #define HWMP_SEQ_LT(a, b) ((int32_t)((a)-(b)) < 0)
124 #define HWMP_SEQ_LEQ(a, b) ((int32_t)((a)-(b)) <= 0)
125 #define HWMP_SEQ_EQ(a, b) ((int32_t)((a)-(b)) == 0)
126 #define HWMP_SEQ_GT(a, b) ((int32_t)((a)-(b)) > 0)
148 uint8_t hs_maxhops; /* max hop count */
156 static int ieee80211_hwmp_pathtimeout = -1;
161 static int ieee80211_hwmp_maxpreq_retries = -1;
166 static int ieee80211_hwmp_net_diameter_traversaltime = -1;
172 static int ieee80211_hwmp_roottimeout = -1;
177 static int ieee80211_hwmp_rootint = -1;
182 static int ieee80211_hwmp_rannint = -1;
188 static int ieee80211_hwmp_rootconfint_internal = -1;
192 "root confirmation interval (ms) (read-only)");
258 KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, in hwmp_vattach()
259 ("not a mesh vap, opmode %d", vap->iv_opmode)); in hwmp_vattach()
268 hs->hs_maxhops = IEEE80211_HWMP_DEFAULT_MAXHOPS; in hwmp_vattach()
269 callout_init(&hs->hs_roottimer, 1); in hwmp_vattach()
270 vap->iv_hwmp = hs; in hwmp_vattach()
276 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_vdetach()
278 callout_drain(&hs->hs_roottimer); in hwmp_vdetach()
279 IEEE80211_FREE(vap->iv_hwmp, M_80211_VAP); in hwmp_vdetach()
280 vap->iv_hwmp = NULL; in hwmp_vdetach()
286 enum ieee80211_state nstate = vap->iv_state; in hwmp_newstate()
287 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_newstate()
289 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", in hwmp_newstate()
294 callout_drain(&hs->hs_roottimer); in hwmp_newstate()
302 * of destinations >= 1, if verification fails -1 is returned.
308 int alloc_sz = -1; in verify_mesh_preq_len()
309 int ndest = -1; in verify_mesh_preq_len()
326 return (-1); in verify_mesh_preq_len()
333 * otherwise -1.
339 int alloc_sz = -1; in verify_mesh_prep_len()
350 return (-1); in verify_mesh_prep_len()
357 * of destinations >= 1, if verification fails -1 is returned.
363 int alloc_sz = -1; in verify_mesh_perr_len()
373 return (-1); in verify_mesh_perr_len()
385 alloc_sz = (iefrm_t - iefrm) - 2; /* action + code */ in verify_mesh_perr_len()
390 return (-1); in verify_mesh_perr_len()
400 struct ieee80211vap *vap = ni->ni_vap; in hwmp_recv_action_meshpath()
407 int ndest = -1; in hwmp_recv_action_meshpath()
410 while (efrm - iefrm > 1) { in hwmp_recv_action_meshpath()
411 IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0); in hwmp_recv_action_meshpath()
420 vap->iv_stats.is_rx_mgtdiscard++; in hwmp_recv_action_meshpath()
424 (ndest - 1) * sizeof(*preq->preq_targets), in hwmp_recv_action_meshpath()
429 preq->preq_ie = *iefrm_t++; in hwmp_recv_action_meshpath()
430 preq->preq_len = *iefrm_t++; in hwmp_recv_action_meshpath()
431 preq->preq_flags = *iefrm_t++; in hwmp_recv_action_meshpath()
432 preq->preq_hopcount = *iefrm_t++; in hwmp_recv_action_meshpath()
433 preq->preq_ttl = *iefrm_t++; in hwmp_recv_action_meshpath()
434 preq->preq_id = le32dec(iefrm_t); iefrm_t += 4; in hwmp_recv_action_meshpath()
435 IEEE80211_ADDR_COPY(preq->preq_origaddr, iefrm_t); in hwmp_recv_action_meshpath()
437 preq->preq_origseq = le32dec(iefrm_t); iefrm_t += 4; in hwmp_recv_action_meshpath()
439 if (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE) { in hwmp_recv_action_meshpath()
441 preq->preq_orig_ext_addr, iefrm_t); in hwmp_recv_action_meshpath()
444 preq->preq_lifetime = le32dec(iefrm_t); iefrm_t += 4; in hwmp_recv_action_meshpath()
445 preq->preq_metric = le32dec(iefrm_t); iefrm_t += 4; in hwmp_recv_action_meshpath()
446 preq->preq_tcount = *iefrm_t++; in hwmp_recv_action_meshpath()
448 for (i = 0; i < preq->preq_tcount; i++) { in hwmp_recv_action_meshpath()
449 preq->preq_targets[i].target_flags = *iefrm_t++; in hwmp_recv_action_meshpath()
451 preq->preq_targets[i].target_addr, iefrm_t); in hwmp_recv_action_meshpath()
453 preq->preq_targets[i].target_seq = in hwmp_recv_action_meshpath()
468 vap->iv_stats.is_rx_mgtdiscard++; in hwmp_recv_action_meshpath()
476 prep->prep_ie = *iefrm_t++; in hwmp_recv_action_meshpath()
477 prep->prep_len = *iefrm_t++; in hwmp_recv_action_meshpath()
478 prep->prep_flags = *iefrm_t++; in hwmp_recv_action_meshpath()
479 prep->prep_hopcount = *iefrm_t++; in hwmp_recv_action_meshpath()
480 prep->prep_ttl = *iefrm_t++; in hwmp_recv_action_meshpath()
481 IEEE80211_ADDR_COPY(prep->prep_targetaddr, iefrm_t); in hwmp_recv_action_meshpath()
483 prep->prep_targetseq = le32dec(iefrm_t); iefrm_t += 4; in hwmp_recv_action_meshpath()
485 if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) { in hwmp_recv_action_meshpath()
487 prep->prep_target_ext_addr, iefrm_t); in hwmp_recv_action_meshpath()
490 prep->prep_lifetime = le32dec(iefrm_t); iefrm_t += 4; in hwmp_recv_action_meshpath()
491 prep->prep_metric = le32dec(iefrm_t); iefrm_t += 4; in hwmp_recv_action_meshpath()
492 IEEE80211_ADDR_COPY(prep->prep_origaddr, iefrm_t); in hwmp_recv_action_meshpath()
494 prep->prep_origseq = le32dec(iefrm_t); iefrm_t += 4; in hwmp_recv_action_meshpath()
508 vap->iv_stats.is_rx_mgtdiscard++; in hwmp_recv_action_meshpath()
512 (ndest - 1) * sizeof(*perr->perr_dests), in hwmp_recv_action_meshpath()
517 perr->perr_ie = *iefrm_t++; in hwmp_recv_action_meshpath()
518 perr->perr_len = *iefrm_t++; in hwmp_recv_action_meshpath()
519 perr->perr_ttl = *iefrm_t++; in hwmp_recv_action_meshpath()
520 perr->perr_ndests = *iefrm_t++; in hwmp_recv_action_meshpath()
522 for (i = 0; i<perr->perr_ndests; i++) { in hwmp_recv_action_meshpath()
523 perr->perr_dests[i].dest_flags = *iefrm_t++; in hwmp_recv_action_meshpath()
525 perr->perr_dests[i].dest_addr, iefrm_t); in hwmp_recv_action_meshpath()
527 perr->perr_dests[i].dest_seq = le32dec(iefrm_t); in hwmp_recv_action_meshpath()
530 if (perr->perr_dests[i].dest_flags & in hwmp_recv_action_meshpath()
533 perr->perr_dests[i].dest_ext_addr, in hwmp_recv_action_meshpath()
537 perr->perr_dests[i].dest_rcode = in hwmp_recv_action_meshpath()
551 if (mrann->rann_len != in hwmp_recv_action_meshpath()
552 sizeof(struct ieee80211_meshrann_ie) - 2) { in hwmp_recv_action_meshpath()
556 vap->iv_stats.is_rx_mgtdiscard++; in hwmp_recv_action_meshpath()
560 rann.rann_seq = le32dec(&mrann->rann_seq); in hwmp_recv_action_meshpath()
561 rann.rann_interval = le32dec(&mrann->rann_interval); in hwmp_recv_action_meshpath()
562 rann.rann_metric = le32dec(&mrann->rann_metric); in hwmp_recv_action_meshpath()
574 vap->iv_stats.is_rx_mgtdiscard++; in hwmp_recv_action_meshpath()
592 ni = ieee80211_ref_node(vap->iv_bss); in hwmp_send_action()
597 ni, ether_sprintf(ni->ni_macaddr), in hwmp_send_action()
605 if (vap->iv_state == IEEE80211_S_CAC) { in hwmp_send_action()
608 vap->iv_stats.is_tx_badstate++; in hwmp_send_action()
613 ic = ni->ni_ic; in hwmp_send_action()
616 ic->ic_headroom + sizeof(struct ieee80211_frame), in hwmp_send_action()
621 vap->iv_stats.is_tx_nobuf++; in hwmp_send_action()
645 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in hwmp_send_action()
649 vap->iv_stats.is_tx_nobuf++; in hwmp_send_action()
657 IEEE80211_NONQOS_TID, vap->iv_myaddr, da, vap->iv_myaddr); in hwmp_send_action()
659 m->m_flags |= M_ENCAP; /* mark encapsulated */ in hwmp_send_action()
664 params.ibp_rate0 = ni->ni_txparms->mgmtrate; in hwmp_send_action()
668 params.ibp_try0 = ni->ni_txparms->maxretry; in hwmp_send_action()
669 params.ibp_power = ni->ni_txpower; in hwmp_send_action()
686 #define PREQ_TFLAGS(n) preq->preq_targets[n].target_flags
687 #define PREQ_TADDR(n) preq->preq_targets[n].target_addr
688 #define PREQ_TSEQ(n) preq->preq_targets[n].target_seq
695 *frm++ = preq->preq_len; /* len already calculated */ in hwmp_add_meshpreq()
696 *frm++ = preq->preq_flags; in hwmp_add_meshpreq()
697 *frm++ = preq->preq_hopcount; in hwmp_add_meshpreq()
698 *frm++ = preq->preq_ttl; in hwmp_add_meshpreq()
699 ADDWORD(frm, preq->preq_id); in hwmp_add_meshpreq()
700 IEEE80211_ADDR_COPY(frm, preq->preq_origaddr); frm += 6; in hwmp_add_meshpreq()
701 ADDWORD(frm, preq->preq_origseq); in hwmp_add_meshpreq()
702 if (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE) { in hwmp_add_meshpreq()
703 IEEE80211_ADDR_COPY(frm, preq->preq_orig_ext_addr); in hwmp_add_meshpreq()
706 ADDWORD(frm, preq->preq_lifetime); in hwmp_add_meshpreq()
707 ADDWORD(frm, preq->preq_metric); in hwmp_add_meshpreq()
708 *frm++ = preq->preq_tcount; in hwmp_add_meshpreq()
709 for (i = 0; i < preq->preq_tcount; i++) { in hwmp_add_meshpreq()
728 *frm++ = prep->prep_len; /* len already calculated */ in hwmp_add_meshprep()
729 *frm++ = prep->prep_flags; in hwmp_add_meshprep()
730 *frm++ = prep->prep_hopcount; in hwmp_add_meshprep()
731 *frm++ = prep->prep_ttl; in hwmp_add_meshprep()
732 IEEE80211_ADDR_COPY(frm, prep->prep_targetaddr); frm += 6; in hwmp_add_meshprep()
733 ADDWORD(frm, prep->prep_targetseq); in hwmp_add_meshprep()
734 if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) { in hwmp_add_meshprep()
735 IEEE80211_ADDR_COPY(frm, prep->prep_target_ext_addr); in hwmp_add_meshprep()
738 ADDWORD(frm, prep->prep_lifetime); in hwmp_add_meshprep()
739 ADDWORD(frm, prep->prep_metric); in hwmp_add_meshprep()
740 IEEE80211_ADDR_COPY(frm, prep->prep_origaddr); frm += 6; in hwmp_add_meshprep()
741 ADDWORD(frm, prep->prep_origseq); in hwmp_add_meshprep()
748 #define PERR_DFLAGS(n) perr->perr_dests[n].dest_flags
749 #define PERR_DADDR(n) perr->perr_dests[n].dest_addr
750 #define PERR_DSEQ(n) perr->perr_dests[n].dest_seq
751 #define PERR_EXTADDR(n) perr->perr_dests[n].dest_ext_addr
752 #define PERR_DRCODE(n) perr->perr_dests[n].dest_rcode
759 *frm++ = perr->perr_len; /* len already calculated */ in hwmp_add_meshperr()
760 *frm++ = perr->perr_ttl; in hwmp_add_meshperr()
761 *frm++ = perr->perr_ndests; in hwmp_add_meshperr()
762 for (i = 0; i < perr->perr_ndests; i++) { in hwmp_add_meshperr()
788 *frm++ = rann->rann_len; in hwmp_add_meshrann()
789 *frm++ = rann->rann_flags; in hwmp_add_meshrann()
790 *frm++ = rann->rann_hopcount; in hwmp_add_meshrann()
791 *frm++ = rann->rann_ttl; in hwmp_add_meshrann()
792 IEEE80211_ADDR_COPY(frm, rann->rann_addr); frm += 6; in hwmp_add_meshrann()
793 ADDWORD(frm, rann->rann_seq); in hwmp_add_meshrann()
794 ADDWORD(frm, rann->rann_interval); in hwmp_add_meshrann()
795 ADDWORD(frm, rann->rann_metric); in hwmp_add_meshrann()
802 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_rootmode_setup()
803 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_rootmode_setup()
805 switch (hs->hs_rootmode) { in hwmp_rootmode_setup()
807 callout_drain(&hs->hs_roottimer); in hwmp_rootmode_setup()
808 ms->ms_flags &= ~IEEE80211_MESHFLAGS_ROOT; in hwmp_rootmode_setup()
812 callout_reset(&hs->hs_roottimer, ieee80211_hwmp_rootint, in hwmp_rootmode_setup()
814 ms->ms_flags |= IEEE80211_MESHFLAGS_ROOT; in hwmp_rootmode_setup()
817 callout_reset(&hs->hs_roottimer, ieee80211_hwmp_rannint, in hwmp_rootmode_setup()
819 ms->ms_flags |= IEEE80211_MESHFLAGS_ROOT; in hwmp_rootmode_setup()
835 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_rootmode_cb()
836 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_rootmode_cb()
839 IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss, in hwmp_rootmode_cb()
843 if (ms->ms_flags & IEEE80211_MESHFLAGS_GATE) in hwmp_rootmode_cb()
845 if (hs->hs_rootmode == IEEE80211_HWMP_ROOTMODE_PROACTIVE) in hwmp_rootmode_cb()
848 preq.preq_ttl = ms->ms_ttl; in hwmp_rootmode_cb()
849 preq.preq_id = ++hs->hs_preqid; in hwmp_rootmode_cb()
850 IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); in hwmp_rootmode_cb()
851 preq.preq_origseq = ++hs->hs_seq; in hwmp_rootmode_cb()
859 vap->iv_stats.is_hwmp_rootreqs++; in hwmp_rootmode_cb()
876 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_rootmode_rann_cb()
877 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_rootmode_rann_cb()
880 IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss, in hwmp_rootmode_rann_cb()
884 if (ms->ms_flags & IEEE80211_MESHFLAGS_GATE) in hwmp_rootmode_rann_cb()
887 rann.rann_ttl = ms->ms_ttl; in hwmp_rootmode_rann_cb()
888 IEEE80211_ADDR_COPY(rann.rann_addr, vap->iv_myaddr); in hwmp_rootmode_rann_cb()
889 rann.rann_seq = ++hs->hs_seq; in hwmp_rootmode_rann_cb()
893 vap->iv_stats.is_hwmp_rootrann++; in hwmp_rootmode_rann_cb()
905 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_update_transmitter()
909 rttran = ieee80211_mesh_rt_find(vap, ni->ni_macaddr); in hwmp_update_transmitter()
911 rttran = ieee80211_mesh_rt_add(vap, ni->ni_macaddr); in hwmp_update_transmitter()
915 ni->ni_macaddr, ":", hwmp_frame); in hwmp_update_transmitter()
916 vap->iv_stats.is_mesh_rtaddfailed++; in hwmp_update_transmitter()
920 metric = ms->ms_pmetric->mpm_metric(ni); in hwmp_update_transmitter()
921 if (!(rttran->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) || in hwmp_update_transmitter()
922 rttran->rt_metric > metric) in hwmp_update_transmitter()
926 rttran->rt_flags & IEEE80211_MESHRT_FLAGS_VALID ? in hwmp_update_transmitter()
927 "prefer" : "update", ni->ni_macaddr, ":", hwmp_frame, in hwmp_update_transmitter()
928 rttran->rt_metric, metric); in hwmp_update_transmitter()
929 IEEE80211_ADDR_COPY(rttran->rt_nexthop, ni->ni_macaddr); in hwmp_update_transmitter()
930 rttran->rt_metric = metric; in hwmp_update_transmitter()
931 rttran->rt_nhops = 1; in hwmp_update_transmitter()
932 ieee80211_mesh_rt_update(rttran, ms->ms_ppath->mpp_inact); in hwmp_update_transmitter()
933 rttran->rt_flags = IEEE80211_MESHRT_FLAGS_VALID; in hwmp_update_transmitter()
937 #define PREQ_TFLAGS(n) preq->preq_targets[n].target_flags
938 #define PREQ_TADDR(n) preq->preq_targets[n].target_addr
939 #define PREQ_TSEQ(n) preq->preq_targets[n].target_seq
944 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_recv_preq()
950 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_recv_preq()
958 if (IEEE80211_ADDR_EQ(vap->iv_myaddr, preq->preq_origaddr)) in hwmp_recv_preq()
962 "received PREQ, orig %6D, targ(0) %6D", preq->preq_origaddr, ":", in hwmp_recv_preq()
971 if (!(ms->ms_flags & IEEE80211_MESHFLAGS_FWD) && in hwmp_recv_preq()
972 (!IEEE80211_ADDR_EQ(vap->iv_myaddr, PREQ_TADDR(0)) || in hwmp_recv_preq()
975 rttarg->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY && in hwmp_recv_preq()
976 IEEE80211_ADDR_EQ(vap->iv_myaddr, rttarg->rt_mesh_gate)))) { in hwmp_recv_preq()
978 preq->preq_origaddr, NULL, "%s", "not accepting PREQ"); in hwmp_recv_preq()
989 if(preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AM && in hwmp_recv_preq()
991 !IEEE80211_ADDR_EQ(vap->iv_myaddr, PREQ_TADDR(0))) { in hwmp_recv_preq()
993 preq->preq_origaddr, NULL, in hwmp_recv_preq()
1001 rtorig = ieee80211_mesh_rt_find(vap, preq->preq_origaddr); in hwmp_recv_preq()
1003 rtorig = ieee80211_mesh_rt_add(vap, preq->preq_origaddr); in hwmp_recv_preq()
1007 preq->preq_origaddr, ":"); in hwmp_recv_preq()
1008 vap->iv_stats.is_mesh_rtaddfailed++; in hwmp_recv_preq()
1012 "adding originator %6D", preq->preq_origaddr, ":"); in hwmp_recv_preq()
1017 preqid = hrorig->hr_preqid; in hwmp_recv_preq()
1018 hrorig->hr_preqid = HWMP_SEQ_MAX(hrorig->hr_preqid, preq->preq_id); in hwmp_recv_preq()
1021 * according to Table 11C-8 for originator mesh STA. in hwmp_recv_preq()
1023 metric = preq->preq_metric + ms->ms_pmetric->mpm_metric(ni); in hwmp_recv_preq()
1024 if (HWMP_SEQ_GT(preq->preq_origseq, hrorig->hr_seq) || in hwmp_recv_preq()
1025 (HWMP_SEQ_EQ(preq->preq_origseq, hrorig->hr_seq) && in hwmp_recv_preq()
1026 metric < rtorig->rt_metric)) { in hwmp_recv_preq()
1027 hrorig->hr_seq = preq->preq_origseq; in hwmp_recv_preq()
1028 IEEE80211_ADDR_COPY(rtorig->rt_nexthop, wh->i_addr2); in hwmp_recv_preq()
1029 rtorig->rt_metric = metric; in hwmp_recv_preq()
1030 rtorig->rt_nhops = preq->preq_hopcount + 1; in hwmp_recv_preq()
1031 ieee80211_mesh_rt_update(rtorig, preq->preq_lifetime); in hwmp_recv_preq()
1036 rtorig->rt_flags = IEEE80211_MESHRT_FLAGS_VALID; in hwmp_recv_preq()
1038 !HWMP_SEQ_EQ(hrtarg->hr_seq, PREQ_TSEQ(0))) || in hwmp_recv_preq()
1039 (rtorig->rt_flags & IEEE80211_MESHRT_FLAGS_VALID && in hwmp_recv_preq()
1040 preqid >= preq->preq_id)) { in hwmp_recv_preq()
1044 preq->preq_origaddr, ":", in hwmp_recv_preq()
1045 preq->preq_origseq, hrorig->hr_seq, in hwmp_recv_preq()
1046 preq->preq_id, preqid); in hwmp_recv_preq()
1057 if (IEEE80211_ADDR_EQ(vap->iv_myaddr, PREQ_TADDR(0)) || in hwmp_recv_preq()
1058 (ms->ms_flags & IEEE80211_MESHFLAGS_GATE && in hwmp_recv_preq()
1060 IEEE80211_ADDR_EQ(vap->iv_myaddr, rttarg->rt_mesh_gate) && in hwmp_recv_preq()
1061 rttarg->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY && in hwmp_recv_preq()
1062 rttarg->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)) { in hwmp_recv_preq()
1067 * number with max of (current and preq->seq) + 1 in hwmp_recv_preq()
1069 hs->hs_seq = HWMP_SEQ_MAX(hs->hs_seq, PREQ_TSEQ(0)) + 1; in hwmp_recv_preq()
1074 IEEE80211_ADDR_COPY(prep.prep_targetaddr, vap->iv_myaddr); in hwmp_recv_preq()
1076 rttarg->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) { in hwmp_recv_preq()
1078 "reply for proxy %6D", rttarg->rt_dest, ":"); in hwmp_recv_preq()
1081 rttarg->rt_dest); in hwmp_recv_preq()
1083 rttarg->rt_ext_seq = hs->hs_seq; in hwmp_recv_preq()
1084 prep.prep_hopcount = rttarg->rt_nhops; in hwmp_recv_preq()
1085 prep.prep_metric = rttarg->rt_metric; in hwmp_recv_preq()
1086 IEEE80211_ADDR_COPY(prep.prep_targetaddr, rttarg->rt_mesh_gate); in hwmp_recv_preq()
1091 prep.prep_ttl = ms->ms_ttl; in hwmp_recv_preq()
1092 prep.prep_targetseq = hs->hs_seq; in hwmp_recv_preq()
1093 prep.prep_lifetime = preq->preq_lifetime; in hwmp_recv_preq()
1094 IEEE80211_ADDR_COPY(prep.prep_origaddr, preq->preq_origaddr); in hwmp_recv_preq()
1095 prep.prep_origseq = preq->preq_origseq; in hwmp_recv_preq()
1098 "reply to %6D", preq->preq_origaddr, ":"); in hwmp_recv_preq()
1099 hwmp_send_prep(vap, wh->i_addr2, &prep); in hwmp_recv_preq()
1103 else if (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE) { in hwmp_recv_preq()
1105 ieee80211_mesh_rt_find(vap, preq->preq_orig_ext_addr); in hwmp_recv_preq()
1108 preq->preq_orig_ext_addr); in hwmp_recv_preq()
1112 preq->preq_orig_ext_addr, ":"); in hwmp_recv_preq()
1113 vap->iv_stats.is_mesh_rtaddfailed++; in hwmp_recv_preq()
1116 IEEE80211_ADDR_COPY(rtorig_ext->rt_mesh_gate, in hwmp_recv_preq()
1117 preq->preq_origaddr); in hwmp_recv_preq()
1119 rtorig_ext->rt_ext_seq = preq->preq_origseq; in hwmp_recv_preq()
1120 ieee80211_mesh_rt_update(rtorig_ext, preq->preq_lifetime); in hwmp_recv_preq()
1129 "root mesh station @ %6D", preq->preq_origaddr, ":"); in hwmp_recv_preq()
1132 if (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_GATE) { in hwmp_recv_preq()
1135 rtorig->rt_flags |= IEEE80211_MESHRT_FLAGS_GATE; in hwmp_recv_preq()
1136 gr = ieee80211_mesh_mark_gate(vap, preq->preq_origaddr, in hwmp_recv_preq()
1138 gr->gr_lastseq = 0; /* NOT GANN */ in hwmp_recv_preq()
1145 if ((rtorig->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0 || in hwmp_recv_preq()
1146 (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_PP)) { in hwmp_recv_preq()
1151 prep.prep_ttl = ms->ms_ttl; in hwmp_recv_preq()
1153 preq->preq_origaddr); in hwmp_recv_preq()
1154 prep.prep_origseq = preq->preq_origseq; in hwmp_recv_preq()
1155 prep.prep_lifetime = preq->preq_lifetime; in hwmp_recv_preq()
1158 vap->iv_myaddr); in hwmp_recv_preq()
1159 prep.prep_targetseq = ++hs->hs_seq; in hwmp_recv_preq()
1160 hwmp_send_prep(vap, rtorig->rt_nexthop, &prep); in hwmp_recv_preq()
1167 if ((preq->preq_tcount == 1) && (preq->preq_ttl > 1) && in hwmp_recv_preq()
1168 (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) { in hwmp_recv_preq()
1178 rttarg->rt_flags & IEEE80211_MESHRT_FLAGS_VALID && in hwmp_recv_preq()
1179 !(rttarg->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY)) { in hwmp_recv_preq()
1191 preq->preq_origaddr, ":"); in hwmp_recv_preq()
1193 prep.prep_hopcount = rttarg->rt_nhops; in hwmp_recv_preq()
1194 prep.prep_ttl = ms->ms_ttl; in hwmp_recv_preq()
1197 prep.prep_targetseq = hrtarg->hr_seq; in hwmp_recv_preq()
1198 prep.prep_lifetime = preq->preq_lifetime; in hwmp_recv_preq()
1199 prep.prep_metric =rttarg->rt_metric; in hwmp_recv_preq()
1201 preq->preq_origaddr); in hwmp_recv_preq()
1202 prep.prep_origseq = hrorig->hr_seq; in hwmp_recv_preq()
1203 hwmp_send_prep(vap, rtorig->rt_nexthop, &prep); in hwmp_recv_preq()
1216 preq->preq_origaddr, ":"); in hwmp_recv_preq()
1218 ppreq.preq_ttl -= 1; in hwmp_recv_preq()
1219 ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni); in hwmp_recv_preq()
1255 preq->preq_ie = IEEE80211_ELEMID_MESHPREQ; in hwmp_send_preq()
1256 preq->preq_len = (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE ? in hwmp_send_preq()
1258 preq->preq_tcount * IEEE80211_MESHPREQ_TRGT_SZ; in hwmp_send_preq()
1259 return hwmp_send_action(vap, da, (uint8_t *)preq, preq->preq_len+2); in hwmp_send_preq()
1266 #define IS_PROXY(rt) (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) in hwmp_recv_prep() argument
1267 #define PROXIED_BY_US(rt) \ in hwmp_recv_prep() argument
1268 (IEEE80211_ADDR_EQ(vap->iv_myaddr, rt->rt_mesh_gate)) in hwmp_recv_prep()
1269 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_recv_prep()
1270 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_recv_prep()
1271 struct ieee80211_mesh_route *rt = NULL; in hwmp_recv_prep() local
1275 struct ieee80211com *ic = vap->iv_ic; in hwmp_recv_prep()
1281 "received PREP, orig %6D, targ %6D", prep->prep_origaddr, ":", in hwmp_recv_prep()
1282 prep->prep_targetaddr, ":"); in hwmp_recv_prep()
1289 rtorig = ieee80211_mesh_rt_find(vap, prep->prep_origaddr); in hwmp_recv_prep()
1290 if ((!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) || in hwmp_recv_prep()
1292 !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)){ in hwmp_recv_prep()
1295 prep->prep_origaddr, ":"); in hwmp_recv_prep()
1308 rt = ieee80211_mesh_rt_find(vap, prep->prep_targetaddr); in hwmp_recv_prep()
1309 if (rt == NULL) { in hwmp_recv_prep()
1310 rt = ieee80211_mesh_rt_add(vap, prep->prep_targetaddr); in hwmp_recv_prep()
1311 if (rt == NULL) { in hwmp_recv_prep()
1314 prep->prep_targetaddr, ":"); in hwmp_recv_prep()
1315 vap->iv_stats.is_mesh_rtaddfailed++; in hwmp_recv_prep()
1319 "adding target %6D", prep->prep_targetaddr, ":"); in hwmp_recv_prep()
1321 hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); in hwmp_recv_prep()
1323 metric = prep->prep_metric + ms->ms_pmetric->mpm_metric(ni); in hwmp_recv_prep()
1324 if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)) { in hwmp_recv_prep()
1325 if (HWMP_SEQ_LT(prep->prep_targetseq, hr->hr_seq)) { in hwmp_recv_prep()
1328 prep->prep_targetaddr, ":", in hwmp_recv_prep()
1329 prep->prep_targetseq, hr->hr_seq); in hwmp_recv_prep()
1331 } else if (HWMP_SEQ_LEQ(prep->prep_targetseq, hr->hr_seq) && in hwmp_recv_prep()
1332 metric > rt->rt_metric) { in hwmp_recv_prep()
1335 prep->prep_targetaddr, ":", in hwmp_recv_prep()
1336 metric, rt->rt_metric); in hwmp_recv_prep()
1343 rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID ? in hwmp_recv_prep()
1345 prep->prep_targetaddr, ":", in hwmp_recv_prep()
1346 rt->rt_nhops, prep->prep_hopcount + 1, in hwmp_recv_prep()
1347 rt->rt_metric, metric); in hwmp_recv_prep()
1349 hr->hr_seq = prep->prep_targetseq; in hwmp_recv_prep()
1350 hr->hr_preqretries = 0; in hwmp_recv_prep()
1351 IEEE80211_ADDR_COPY(rt->rt_nexthop, ni->ni_macaddr); in hwmp_recv_prep()
1352 rt->rt_metric = metric; in hwmp_recv_prep()
1353 rt->rt_nhops = prep->prep_hopcount + 1; in hwmp_recv_prep()
1354 ieee80211_mesh_rt_update(rt, prep->prep_lifetime); in hwmp_recv_prep()
1355 if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_DISCOVER) { in hwmp_recv_prep()
1357 rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_DISCOVER; in hwmp_recv_prep()
1359 rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID; /* mark valid */ in hwmp_recv_prep()
1367 if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) && in hwmp_recv_prep()
1368 prep->prep_ttl > 1 && in hwmp_recv_prep()
1369 prep->prep_hopcount < hs->hs_maxhops) { in hwmp_recv_prep()
1380 prep->prep_origaddr, ":"); in hwmp_recv_prep()
1386 prep->prep_targetaddr, ":"); in hwmp_recv_prep()
1390 pprep.prep_ttl -= 1; in hwmp_recv_prep()
1391 pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni); in hwmp_recv_prep()
1392 hwmp_send_prep(vap, rtorig->rt_nexthop, &pprep); in hwmp_recv_prep()
1402 if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) { in hwmp_recv_prep()
1404 prep->prep_target_ext_addr); in hwmp_recv_prep()
1407 prep->prep_target_ext_addr); in hwmp_recv_prep()
1411 prep->prep_targetaddr, ":"); in hwmp_recv_prep()
1412 vap->iv_stats.is_mesh_rtaddfailed++; in hwmp_recv_prep()
1418 rtext->rt_flags & IEEE80211_MESHRT_FLAGS_VALID ? in hwmp_recv_prep()
1420 prep->prep_target_ext_addr, ":", in hwmp_recv_prep()
1421 rtext->rt_nhops, prep->prep_hopcount + 1, in hwmp_recv_prep()
1422 rtext->rt_metric, metric); in hwmp_recv_prep()
1424 rtext->rt_flags = IEEE80211_MESHRT_FLAGS_PROXY | in hwmp_recv_prep()
1426 IEEE80211_ADDR_COPY(rtext->rt_dest, in hwmp_recv_prep()
1427 prep->prep_target_ext_addr); in hwmp_recv_prep()
1428 IEEE80211_ADDR_COPY(rtext->rt_mesh_gate, in hwmp_recv_prep()
1429 prep->prep_targetaddr); in hwmp_recv_prep()
1430 IEEE80211_ADDR_COPY(rtext->rt_nexthop, wh->i_addr2); in hwmp_recv_prep()
1431 rtext->rt_metric = metric; in hwmp_recv_prep()
1432 rtext->rt_lifetime = prep->prep_lifetime; in hwmp_recv_prep()
1433 rtext->rt_nhops = prep->prep_hopcount + 1; in hwmp_recv_prep()
1434 rtext->rt_ext_seq = prep->prep_origseq; /* new proxy seq */ in hwmp_recv_prep()
1447 addr = prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE ? in hwmp_recv_prep()
1448 prep->prep_target_ext_addr : prep->prep_targetaddr; in hwmp_recv_prep()
1449 m = ieee80211_ageq_remove(&ic->ic_stageq, in hwmp_recv_prep()
1454 * All frames in the stageq here should be non-M_ENCAP; or things in hwmp_recv_prep()
1458 next = m->m_nextpkt; in hwmp_recv_prep()
1459 m->m_nextpkt = NULL; in hwmp_recv_prep()
1461 "flush queued frame %p len %d", m, m->m_pkthdr.len); in hwmp_recv_prep()
1488 prep->prep_ie = IEEE80211_ELEMID_MESHPREP; in hwmp_send_prep()
1489 prep->prep_len = prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE ? in hwmp_send_prep()
1491 return hwmp_send_action(vap, da, (uint8_t *)prep, prep->prep_len + 2); in hwmp_send_prep()
1501 struct ieee80211vap *vap = ni->ni_vap; in hwmp_peerdown()
1502 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_peerdown()
1504 struct ieee80211_mesh_route *rt; in hwmp_peerdown() local
1507 rt = ieee80211_mesh_rt_find(vap, ni->ni_macaddr); in hwmp_peerdown()
1508 if (rt == NULL) in hwmp_peerdown()
1510 hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); in hwmp_peerdown()
1513 perr.perr_ttl = ms->ms_ttl; in hwmp_peerdown()
1516 if (hr->hr_seq == 0) in hwmp_peerdown()
1519 IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest); in hwmp_peerdown()
1520 PERR_DSEQ(0) = ++hr->hr_seq; in hwmp_peerdown()
1523 ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr); in hwmp_peerdown()
1531 #define PERR_DFLAGS(n) perr->perr_dests[n].dest_flags
1532 #define PERR_DADDR(n) perr->perr_dests[n].dest_addr
1533 #define PERR_DSEQ(n) perr->perr_dests[n].dest_seq
1534 #define PERR_DEXTADDR(n) perr->perr_dests[n].dest_ext_addr
1539 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_recv_perr()
1540 struct ieee80211_mesh_route *rt = NULL; in hwmp_recv_perr() local
1547 "received PERR from %6D", wh->i_addr2, ":"); in hwmp_recv_perr()
1552 if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) { in hwmp_recv_perr()
1554 pperr = IEEE80211_MALLOC(sizeof(*perr) + 31*sizeof(*perr->perr_dests), in hwmp_recv_perr()
1563 for (i = 0; i < perr->perr_ndests; i++) { in hwmp_recv_perr()
1564 rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i)); in hwmp_recv_perr()
1565 if (rt == NULL) in hwmp_recv_perr()
1567 if (!IEEE80211_ADDR_EQ(rt->rt_nexthop, wh->i_addr2)) in hwmp_recv_perr()
1572 memcpy(&pperr->perr_dests[j], &perr->perr_dests[i], in hwmp_recv_perr()
1573 sizeof(*perr->perr_dests)); in hwmp_recv_perr()
1574 hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); in hwmp_recv_perr()
1578 hr->hr_seq++; in hwmp_recv_perr()
1580 pperr->perr_dests[j].dest_seq = in hwmp_recv_perr()
1581 hr->hr_seq; in hwmp_recv_perr()
1584 hr->hr_seq = PERR_DSEQ(i); in hwmp_recv_perr()
1586 rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID; in hwmp_recv_perr()
1590 if(HWMP_SEQ_GT(PERR_DSEQ(i), hr->hr_seq)) { in hwmp_recv_perr()
1591 hr->hr_seq = PERR_DSEQ(i); in hwmp_recv_perr()
1592 rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID; in hwmp_recv_perr()
1599 rt_ext->rt_flags &= in hwmp_recv_perr()
1621 if (forward && perr->perr_ttl > 1) { in hwmp_recv_perr()
1623 "propagate PERR from %6D", wh->i_addr2, ":"); in hwmp_recv_perr()
1624 pperr->perr_ndests = j; in hwmp_recv_perr()
1625 pperr->perr_ttl--; in hwmp_recv_perr()
1642 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_send_perr()
1649 if (ratecheck(&hs->hs_lastperr, &ieee80211_hwmp_perrminint) == 0) in hwmp_send_perr()
1651 getmicrouptime(&hs->hs_lastperr); in hwmp_send_perr()
1662 perr->perr_ie = IEEE80211_ELEMID_MESHPERR; in hwmp_send_perr()
1664 for (i = 0; i<perr->perr_ndests; i++) { in hwmp_send_perr()
1665 if (perr->perr_dests[i].dest_flags & in hwmp_send_perr()
1672 perr->perr_len =length; in hwmp_send_perr()
1673 return hwmp_send_action(vap, da, (uint8_t *)perr, perr->perr_len+2); in hwmp_send_perr()
1679 * a mesh STA is unable to forward an MSDU/MMPDU to a next-hop mesh STA.
1689 struct ieee80211_mesh_route *rt, int rcode) in hwmp_senderror() argument
1691 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_senderror()
1695 if (rt != NULL) in hwmp_senderror()
1696 hr = IEEE80211_MESH_ROUTE_PRIV(rt, in hwmp_senderror()
1700 perr.perr_ttl = ms->ms_ttl; in hwmp_senderror()
1710 KASSERT(rt != NULL, ("no proxy info for sending PERR")); in hwmp_senderror()
1711 KASSERT(rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY, in hwmp_senderror()
1714 IEEE80211_ADDR_COPY(PERR_DADDR(0), vap->iv_myaddr); in hwmp_senderror()
1715 PERR_DSEQ(0) = rt->rt_ext_seq; in hwmp_senderror()
1719 KASSERT(rt != NULL, ("no route info for sending PERR")); in hwmp_senderror()
1721 PERR_DSEQ(0) = hr->hr_seq; in hwmp_senderror()
1738 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_recv_rann()
1739 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_recv_rann()
1740 struct ieee80211_mesh_route *rt = NULL; in hwmp_recv_rann() local
1745 if (IEEE80211_ADDR_EQ(rann->rann_addr, vap->iv_myaddr)) in hwmp_recv_rann()
1748 rt = ieee80211_mesh_rt_find(vap, rann->rann_addr); in hwmp_recv_rann()
1749 if (rt != NULL && rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) { in hwmp_recv_rann()
1750 hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); in hwmp_recv_rann()
1753 if (HWMP_SEQ_LT(rann->rann_seq, hr->hr_seq)) { in hwmp_recv_rann()
1755 "RANN seq %u < %u", rann->rann_seq, hr->hr_seq); in hwmp_recv_rann()
1761 if (HWMP_SEQ_EQ(rann->rann_seq, hr->hr_seq) && in hwmp_recv_rann()
1762 rann->rann_metric > rt->rt_metric) { in hwmp_recv_rann()
1764 "RANN metric %u > %u", rann->rann_metric, rt->rt_metric); in hwmp_recv_rann()
1771 ieee80211_hwmp_rannint = rann->rann_interval; /* XXX: mtx lock? */ in hwmp_recv_rann()
1773 if (rt == NULL) { in hwmp_recv_rann()
1774 rt = ieee80211_mesh_rt_add(vap, rann->rann_addr); in hwmp_recv_rann()
1775 if (rt == NULL) { in hwmp_recv_rann()
1778 rann->rann_addr, ":"); in hwmp_recv_rann()
1779 vap->iv_stats.is_mesh_rtaddfailed++; in hwmp_recv_rann()
1783 hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); in hwmp_recv_rann()
1785 if (rann->rann_flags & IEEE80211_MESHRANN_FLAGS_GATE) { in hwmp_recv_rann()
1788 rt->rt_flags |= IEEE80211_MESHRT_FLAGS_GATE; in hwmp_recv_rann()
1789 gr = ieee80211_mesh_mark_gate(vap, rann->rann_addr, in hwmp_recv_rann()
1790 rt); in hwmp_recv_rann()
1791 gr->gr_lastseq = 0; /* NOT GANN */ in hwmp_recv_rann()
1794 ieee80211_mesh_rt_update(rt, in hwmp_recv_rann()
1799 preq.preq_ttl = ms->ms_ttl; in hwmp_recv_rann()
1801 IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); in hwmp_recv_rann()
1802 preq.preq_origseq = ++hs->hs_seq; in hwmp_recv_rann()
1808 IEEE80211_ADDR_COPY(preq.preq_targets[0].target_addr, rann->rann_addr); in hwmp_recv_rann()
1809 preq.preq_targets[0].target_seq = rann->rann_seq; in hwmp_recv_rann()
1811 hwmp_send_preq(vap, wh->i_addr2, &preq, &hr->hr_lastrootconf, in hwmp_recv_rann()
1815 if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID && in hwmp_recv_rann()
1816 rann->rann_ttl > 1 && in hwmp_recv_rann()
1817 ms->ms_flags & IEEE80211_MESHFLAGS_FWD) { in hwmp_recv_rann()
1818 hr->hr_seq = rann->rann_seq; in hwmp_recv_rann()
1821 prann.rann_ttl -= 1; in hwmp_recv_rann()
1822 prann.rann_metric += ms->ms_pmetric->mpm_metric(ni); in hwmp_recv_rann()
1841 rann->rann_ie = IEEE80211_ELEMID_MESHRANN; in hwmp_send_rann()
1842 rann->rann_len = IEEE80211_MESHRANN_BASE_SZ; in hwmp_send_rann()
1843 return hwmp_send_action(vap, da, (uint8_t *)rann, rann->rann_len + 2); in hwmp_send_rann()
1852 struct ieee80211_mesh_route *rt = arg; in hwmp_rediscover_cb() local
1853 struct ieee80211vap *vap = rt->rt_vap; in hwmp_rediscover_cb()
1854 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_rediscover_cb()
1855 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_rediscover_cb()
1859 if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)) in hwmp_rediscover_cb()
1862 hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); in hwmp_rediscover_cb()
1863 if (hr->hr_preqretries >= in hwmp_rediscover_cb()
1866 rt->rt_dest, "%s", in hwmp_rediscover_cb()
1867 "max number of discovery, send queued frames to GATE"); in hwmp_rediscover_cb()
1868 ieee80211_mesh_forward_to_gates(vap, rt); in hwmp_rediscover_cb()
1869 vap->iv_stats.is_mesh_fwd_nopath++; in hwmp_rediscover_cb()
1873 hr->hr_preqretries++; in hwmp_rediscover_cb()
1875 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, rt->rt_dest, in hwmp_rediscover_cb()
1876 "start path rediscovery , target seq %u", hr->hr_seq); in hwmp_rediscover_cb()
1883 preq.preq_ttl = ms->ms_ttl; in hwmp_rediscover_cb()
1884 preq.preq_id = ++hs->hs_preqid; in hwmp_rediscover_cb()
1885 IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); in hwmp_rediscover_cb()
1886 preq.preq_origseq = hr->hr_origseq; in hwmp_rediscover_cb()
1890 IEEE80211_ADDR_COPY(PREQ_TADDR(0), rt->rt_dest); in hwmp_rediscover_cb()
1897 hwmp_send_preq(vap, broadcastaddr, &preq, &hr->hr_lastpreq, in hwmp_rediscover_cb()
1899 callout_reset(&rt->rt_discovery, in hwmp_rediscover_cb()
1901 hwmp_rediscover_cb, rt); in hwmp_rediscover_cb()
1908 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_discover()
1909 struct ieee80211_mesh_state *ms = vap->iv_mesh; in hwmp_discover()
1910 struct ieee80211_mesh_route *rt = NULL; in hwmp_discover() local
1916 KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, in hwmp_discover()
1917 ("not a mesh vap, opmode %d", vap->iv_opmode)); in hwmp_discover()
1919 KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest), in hwmp_discover()
1924 rt = ieee80211_mesh_rt_find(vap, dest); in hwmp_discover()
1925 if (rt == NULL) { in hwmp_discover()
1926 rt = ieee80211_mesh_rt_add(vap, dest); in hwmp_discover()
1927 if (rt == NULL) { in hwmp_discover()
1931 vap->iv_stats.is_mesh_rtaddfailed++; in hwmp_discover()
1935 hr = IEEE80211_MESH_ROUTE_PRIV(rt, in hwmp_discover()
1937 if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_DISCOVER) { in hwmp_discover()
1943 if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) { in hwmp_discover()
1944 if (hr->hr_lastdiscovery != 0 && in hwmp_discover()
1945 (ticks - hr->hr_lastdiscovery < in hwmp_discover()
1953 hr->hr_lastdiscovery = ticks; in hwmp_discover()
1954 if (hr->hr_preqretries >= in hwmp_discover()
1958 "no valid path , max number of discovery"); in hwmp_discover()
1959 vap->iv_stats.is_mesh_fwd_nopath++; in hwmp_discover()
1962 rt->rt_flags = IEEE80211_MESHRT_FLAGS_DISCOVER; in hwmp_discover()
1963 hr->hr_preqretries++; in hwmp_discover()
1964 if (hr->hr_origseq == 0) in hwmp_discover()
1965 hr->hr_origseq = ++hs->hs_seq; in hwmp_discover()
1966 rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL; in hwmp_discover()
1971 mtod(m, struct ether_header *)->ether_shost), in hwmp_discover()
1972 hr->hr_seq); in hwmp_discover()
1979 preq.preq_ttl = ms->ms_ttl; in hwmp_discover()
1980 preq.preq_id = ++hs->hs_preqid; in hwmp_discover()
1981 IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); in hwmp_discover()
1982 preq.preq_origseq = hr->hr_origseq; in hwmp_discover()
1995 &hr->hr_lastpreq, &ieee80211_hwmp_preqminint); in hwmp_discover()
1996 callout_reset(&rt->rt_discovery, in hwmp_discover()
1998 hwmp_rediscover_cb, rt); in hwmp_discover()
2000 if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) in hwmp_discover()
2001 ni = ieee80211_find_txnode(vap, rt->rt_nexthop); in hwmp_discover()
2011 struct ieee80211com *ic = vap->iv_ic; in hwmp_discover()
2019 MPASS((m->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0); in hwmp_discover()
2020 m->m_pkthdr.rcvif = (void *)(uintptr_t) in hwmp_discover()
2023 ieee80211_ageq_append(&ic->ic_stageq, m, in hwmp_discover()
2040 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_ioctl_get80211()
2043 if (vap->iv_opmode != IEEE80211_M_MBSS) in hwmp_ioctl_get80211()
2046 switch (ireq->i_type) { in hwmp_ioctl_get80211()
2048 ireq->i_val = hs->hs_rootmode; in hwmp_ioctl_get80211()
2051 ireq->i_val = hs->hs_maxhops; in hwmp_ioctl_get80211()
2063 struct ieee80211_hwmp_state *hs = vap->iv_hwmp; in hwmp_ioctl_set80211()
2066 if (vap->iv_opmode != IEEE80211_M_MBSS) in hwmp_ioctl_set80211()
2069 switch (ireq->i_type) { in hwmp_ioctl_set80211()
2071 if (ireq->i_val < 0 || ireq->i_val > 3) in hwmp_ioctl_set80211()
2073 hs->hs_rootmode = ireq->i_val; in hwmp_ioctl_set80211()
2077 if (ireq->i_val <= 0 || ireq->i_val > 255) in hwmp_ioctl_set80211()
2079 hs->hs_maxhops = ireq->i_val; in hwmp_ioctl_set80211()