Lines Matching +full:max +full:- +full:rx +full:- +full:timeout +full:- +full:ms
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
102 * Timeout values come from the specification and are in milliseconds.
106 static int ieee80211_mesh_gateint = -1;
110 "mesh gate interval (ms)");
111 static int ieee80211_mesh_retrytimeout = -1;
115 "Retry timeout (msec)");
116 static int ieee80211_mesh_holdingtimeout = -1;
121 "Holding state timeout (msec)");
122 static int ieee80211_mesh_confirmtimeout = -1;
126 "Confirm state timeout (msec)");
127 static int ieee80211_mesh_backofftimeout = -1;
131 "Backoff timeout (msec). This is to throutles peering forever when "
182 mesh_rt_find_locked(struct ieee80211_mesh_state *ms, in mesh_rt_find_locked() argument
187 MESH_RT_LOCK_ASSERT(ms); in mesh_rt_find_locked()
189 TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) { in mesh_rt_find_locked()
190 if (IEEE80211_ADDR_EQ(dest, rt->rt_dest)) in mesh_rt_find_locked()
200 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_rt_add_locked() local
206 MESH_RT_LOCK_ASSERT(ms); in mesh_rt_add_locked()
209 ms->ms_ppath->mpp_privlen, M_80211_MESH_RT, in mesh_rt_add_locked()
212 rt->rt_vap = vap; in mesh_rt_add_locked()
213 IEEE80211_ADDR_COPY(rt->rt_dest, dest); in mesh_rt_add_locked()
214 rt->rt_priv = (void *)ALIGN(&rt[1]); in mesh_rt_add_locked()
216 callout_init(&rt->rt_discovery, 1); in mesh_rt_add_locked()
217 rt->rt_updtime = ticks; /* create time */ in mesh_rt_add_locked()
218 TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next); in mesh_rt_add_locked()
227 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_rt_find() local
230 MESH_RT_LOCK(ms); in ieee80211_mesh_rt_find()
231 rt = mesh_rt_find_locked(ms, dest); in ieee80211_mesh_rt_find()
232 MESH_RT_UNLOCK(ms); in ieee80211_mesh_rt_find()
240 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_rt_add() local
245 KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest), in ieee80211_mesh_rt_add()
248 MESH_RT_LOCK(ms); in ieee80211_mesh_rt_add()
250 MESH_RT_UNLOCK(ms); in ieee80211_mesh_rt_add()
271 if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY && rt->rt_nhops == 0) { in ieee80211_mesh_rt_update()
273 return rt->rt_lifetime; in ieee80211_mesh_rt_update()
276 timesince = ticks_to_msecs(now - rt->rt_updtime); in ieee80211_mesh_rt_update()
277 rt->rt_updtime = now; in ieee80211_mesh_rt_update()
278 if (timesince >= rt->rt_lifetime) { in ieee80211_mesh_rt_update()
280 rt->rt_lifetime = new_lifetime; in ieee80211_mesh_rt_update()
283 rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID; in ieee80211_mesh_rt_update()
284 rt->rt_lifetime = 0; in ieee80211_mesh_rt_update()
288 rt->rt_lifetime = rt->rt_lifetime - timesince; in ieee80211_mesh_rt_update()
289 rt->rt_lifetime = MESH_ROUTE_LIFETIME_MAX( in ieee80211_mesh_rt_update()
290 new_lifetime, rt->rt_lifetime); in ieee80211_mesh_rt_update()
292 lifetime = rt->rt_lifetime; in ieee80211_mesh_rt_update()
305 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_proxy_check() local
308 MESH_RT_LOCK(ms); in ieee80211_mesh_proxy_check()
309 rt = mesh_rt_find_locked(ms, dest); in ieee80211_mesh_proxy_check()
315 vap->iv_stats.is_mesh_rtaddfailed++; in ieee80211_mesh_proxy_check()
319 IEEE80211_ADDR_COPY(rt->rt_mesh_gate, vap->iv_myaddr); in ieee80211_mesh_proxy_check()
320 IEEE80211_ADDR_COPY(rt->rt_nexthop, vap->iv_myaddr); in ieee80211_mesh_proxy_check()
321 rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID in ieee80211_mesh_proxy_check()
324 } else if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) { in ieee80211_mesh_proxy_check()
325 KASSERT(rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY, in ieee80211_mesh_proxy_check()
327 struct ieee80211com *ic = vap->iv_ic; in ieee80211_mesh_proxy_check()
336 IEEE80211_ADDR_COPY(rt->rt_nexthop, vap->iv_myaddr); in ieee80211_mesh_proxy_check()
337 rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID in ieee80211_mesh_proxy_check()
340 ieee80211_ageq_drain_node(&ic->ic_stageq, in ieee80211_mesh_proxy_check()
344 MESH_RT_UNLOCK(ms); in ieee80211_mesh_proxy_check()
348 mesh_rt_del(struct ieee80211_mesh_state *ms, struct ieee80211_mesh_route *rt) in mesh_rt_del() argument
350 TAILQ_REMOVE(&ms->ms_routes, rt, rt_next); in mesh_rt_del()
356 callout_drain(&rt->rt_discovery); in mesh_rt_del()
365 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_rt_del() local
368 MESH_RT_LOCK(ms); in ieee80211_mesh_rt_del()
369 TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) { in ieee80211_mesh_rt_del()
370 if (IEEE80211_ADDR_EQ(rt->rt_dest, dest)) { in ieee80211_mesh_rt_del()
371 if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) { in ieee80211_mesh_rt_del()
372 ms->ms_ppath->mpp_senderror(vap, dest, rt, in ieee80211_mesh_rt_del()
375 ms->ms_ppath->mpp_senderror(vap, dest, rt, in ieee80211_mesh_rt_del()
378 mesh_rt_del(ms, rt); in ieee80211_mesh_rt_del()
379 MESH_RT_UNLOCK(ms); in ieee80211_mesh_rt_del()
383 MESH_RT_UNLOCK(ms); in ieee80211_mesh_rt_del()
389 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_rt_flush() local
392 if (ms == NULL) in ieee80211_mesh_rt_flush()
394 MESH_RT_LOCK(ms); in ieee80211_mesh_rt_flush()
395 TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) in ieee80211_mesh_rt_flush()
396 mesh_rt_del(ms, rt); in ieee80211_mesh_rt_flush()
397 MESH_RT_UNLOCK(ms); in ieee80211_mesh_rt_flush()
404 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_rt_flush_peer() local
407 MESH_RT_LOCK(ms); in ieee80211_mesh_rt_flush_peer()
408 TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) { in ieee80211_mesh_rt_flush_peer()
409 if (IEEE80211_ADDR_EQ(rt->rt_nexthop, peer)) in ieee80211_mesh_rt_flush_peer()
410 mesh_rt_del(ms, rt); in ieee80211_mesh_rt_flush_peer()
412 MESH_RT_UNLOCK(ms); in ieee80211_mesh_rt_flush_peer()
422 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_rt_flush_invalid() local
425 if (ms == NULL) in mesh_rt_flush_invalid()
427 MESH_RT_LOCK(ms); in mesh_rt_flush_invalid()
428 TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) { in mesh_rt_flush_invalid()
430 if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_DISCOVER) in mesh_rt_flush_invalid()
433 if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) in mesh_rt_flush_invalid()
434 mesh_rt_del(ms, rt); in mesh_rt_flush_invalid()
436 MESH_RT_UNLOCK(ms); in mesh_rt_flush_invalid()
442 int i, firstempty = -1; in ieee80211_mesh_register_proto_path()
445 if (strncmp(mpp->mpp_descr, mesh_proto_paths[i].mpp_descr, in ieee80211_mesh_register_proto_path()
448 if (!mesh_proto_paths[i].mpp_active && firstempty == -1) in ieee80211_mesh_register_proto_path()
462 int i, firstempty = -1; in ieee80211_mesh_register_proto_metric()
465 if (strncmp(mpm->mpm_descr, mesh_proto_metrics[i].mpm_descr, in ieee80211_mesh_register_proto_metric()
468 if (!mesh_proto_metrics[i].mpm_active && firstempty == -1) in ieee80211_mesh_register_proto_metric()
481 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_select_proto_path() local
486 ms->ms_ppath = &mesh_proto_paths[i]; in mesh_select_proto_path()
496 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_select_proto_metric() local
501 ms->ms_pmetric = &mesh_proto_metrics[i]; in mesh_select_proto_metric()
511 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_gatemode_setup() local
519 if (ms->ms_flags & IEEE80211_MESHFLAGS_ROOT || in mesh_gatemode_setup()
520 (ms->ms_flags & IEEE80211_MESHFLAGS_GATE) == 0) { in mesh_gatemode_setup()
521 callout_drain(&ms->ms_gatetimer); in mesh_gatemode_setup()
524 callout_reset(&ms->ms_gatetimer, ieee80211_mesh_gateint, in mesh_gatemode_setup()
532 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_gatemode_cb() local
537 gann.gann_ttl = ms->ms_ttl; in mesh_gatemode_cb()
538 IEEE80211_ADDR_COPY(gann.gann_addr, vap->iv_myaddr); in mesh_gatemode_cb()
539 gann.gann_seq = ms->ms_gateseq++; in mesh_gatemode_cb()
542 IEEE80211_NOTE(vap, IEEE80211_MSG_MESH, vap->iv_bss, in mesh_gatemode_cb()
545 ieee80211_send_action(vap->iv_bss, IEEE80211_ACTION_CAT_MESH, in mesh_gatemode_cb()
610 ic->ic_vattach[IEEE80211_M_MBSS] = mesh_vattach; in ieee80211_mesh_attach()
621 struct ieee80211com *ic = ni->ni_ic; in mesh_vdetach_peers()
624 if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED) { in mesh_vdetach_peers()
625 args[0] = ni->ni_mlpid; in mesh_vdetach_peers()
626 args[1] = ni->ni_mllid; in mesh_vdetach_peers()
633 callout_drain(&ni->ni_mltimer); in mesh_vdetach_peers()
635 ieee80211_ageq_drain_node(&ic->ic_stageq, in mesh_vdetach_peers()
636 (void *)(uintptr_t) ieee80211_mac_hash(ic, ni->ni_macaddr)); in mesh_vdetach_peers()
642 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_vdetach() local
644 callout_drain(&ms->ms_cleantimer); in mesh_vdetach()
645 ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_vdetach_peers, in mesh_vdetach()
648 MESH_RT_LOCK_DESTROY(ms); in mesh_vdetach()
649 ms->ms_ppath->mpp_vdetach(vap); in mesh_vdetach()
650 IEEE80211_FREE(vap->iv_mesh, M_80211_VAP); in mesh_vdetach()
651 vap->iv_mesh = NULL; in mesh_vdetach()
657 struct ieee80211_mesh_state *ms; in mesh_vattach() local
658 vap->iv_newstate = mesh_newstate; in mesh_vattach()
659 vap->iv_input = mesh_input; in mesh_vattach()
660 vap->iv_opdetach = mesh_vdetach; in mesh_vattach()
661 vap->iv_recv_mgmt = mesh_recv_mgmt; in mesh_vattach()
662 vap->iv_recv_ctl = mesh_recv_ctl; in mesh_vattach()
663 ms = IEEE80211_MALLOC(sizeof(struct ieee80211_mesh_state), M_80211_VAP, in mesh_vattach()
665 if (ms == NULL) { in mesh_vattach()
670 vap->iv_mesh = ms; in mesh_vattach()
671 ms->ms_seq = 0; in mesh_vattach()
672 ms->ms_flags = (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_FWD); in mesh_vattach()
673 ms->ms_ttl = IEEE80211_MESH_DEFAULT_TTL; in mesh_vattach()
674 TAILQ_INIT(&ms->ms_known_gates); in mesh_vattach()
675 TAILQ_INIT(&ms->ms_routes); in mesh_vattach()
676 MESH_RT_LOCK_INIT(ms, "MBSS"); in mesh_vattach()
677 callout_init(&ms->ms_cleantimer, 1); in mesh_vattach()
678 callout_init(&ms->ms_gatetimer, 1); in mesh_vattach()
679 ms->ms_gateseq = 0; in mesh_vattach()
681 KASSERT(ms->ms_pmetric, ("ms_pmetric == NULL")); in mesh_vattach()
683 KASSERT(ms->ms_ppath, ("ms_ppath == NULL")); in mesh_vattach()
684 ms->ms_ppath->mpp_vattach(vap); in mesh_vattach()
693 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_newstate() local
694 struct ieee80211com *ic = vap->iv_ic; in mesh_newstate()
700 ostate = vap->iv_state; in mesh_newstate()
701 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", in mesh_newstate()
704 vap->iv_state = nstate; /* state transition */ in mesh_newstate()
707 ni = vap->iv_bss; /* NB: no reference held */ in mesh_newstate()
709 callout_drain(&ms->ms_cleantimer); in mesh_newstate()
710 callout_drain(&ms->ms_gatetimer); in mesh_newstate()
722 ieee80211_iterate_nodes(&ic->ic_sta, in mesh_newstate()
729 /* NB: optimize INIT -> INIT case */ in mesh_newstate()
737 if (vap->iv_des_chan != IEEE80211_CHAN_ANYC && in mesh_newstate()
738 !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan) && in mesh_newstate()
739 ms->ms_idlen != 0) { in mesh_newstate()
744 ieee80211_create_ibss(vap, vap->iv_des_chan); in mesh_newstate()
754 if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { in mesh_newstate()
756 vap->iv_scanreq_flags, in mesh_newstate()
757 vap->iv_scanreq_duration, in mesh_newstate()
758 vap->iv_scanreq_mindwell, in mesh_newstate()
759 vap->iv_scanreq_maxdwell, in mesh_newstate()
760 vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); in mesh_newstate()
761 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; in mesh_newstate()
783 * back to do a RUN->RUN state change. in mesh_newstate()
787 ic->ic_curchan, vap->iv_flags_ht)); in mesh_newstate()
803 ieee80211_iterate_nodes(&ic->ic_sta, sta_csa, vap); in mesh_newstate()
810 ieee80211_ht_adjust_channel(ic, ic->ic_curchan, in mesh_newstate()
811 ieee80211_htchanflags(ni->ni_chan))); in mesh_newstate()
820 ether_sprintf(ni->ni_meshid)); in mesh_newstate()
821 ieee80211_print_essid(ni->ni_meshid, in mesh_newstate()
822 ni->ni_meshidlen); in mesh_newstate()
825 ieee80211_chan2ieee(ic, ic->ic_curchan)); in mesh_newstate()
833 callout_reset(&ms->ms_cleantimer, ms->ms_ppath->mpp_inact, in mesh_newstate()
841 ms->ms_ppath->mpp_newstate(vap, ostate, arg); in mesh_newstate()
849 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_rt_cleanup_cb() local
852 callout_reset(&ms->ms_cleantimer, ms->ms_ppath->mpp_inact, in mesh_rt_cleanup_cb()
865 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_mark_gate() local
869 MESH_RT_LOCK(ms); in ieee80211_mesh_mark_gate()
870 TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, next) { in ieee80211_mesh_mark_gate()
871 if (IEEE80211_ADDR_EQ(gr->gr_addr, addr)) { in ieee80211_mesh_mark_gate()
880 "%s", "stored new gate information from pro-PREQ."); in ieee80211_mesh_mark_gate()
884 IEEE80211_ADDR_COPY(gr->gr_addr, addr); in ieee80211_mesh_mark_gate()
885 TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next); in ieee80211_mesh_mark_gate()
887 gr->gr_route = rt; in ieee80211_mesh_mark_gate()
889 MESH_RT_UNLOCK(ms); in ieee80211_mesh_mark_gate()
900 struct ieee80211vap *vap = ni->ni_vap; in mesh_linkchange()
901 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_linkchange() local
913 ni, "peer link: %s -> %s", in mesh_linkchange()
914 meshlinkstates[ni->ni_mlstate], meshlinkstates[state]); in mesh_linkchange()
918 ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) { in mesh_linkchange()
919 KASSERT(ms->ms_neighbors < 65535, ("neighbor count overflow")); in mesh_linkchange()
920 ms->ms_neighbors++; in mesh_linkchange()
922 } else if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED && in mesh_linkchange()
924 KASSERT(ms->ms_neighbors > 0, ("neighbor count 0")); in mesh_linkchange()
925 ms->ms_neighbors--; in mesh_linkchange()
928 ni->ni_mlstate = state; in mesh_linkchange()
931 ms->ms_ppath->mpp_peerdown(ni); in mesh_linkchange()
934 ieee80211_mesh_discover(vap, ni->ni_macaddr, NULL); in mesh_linkchange()
950 if (*r == ni->ni_mllid) in mesh_checkid()
962 ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_checkid, &r); in mesh_generateid()
963 maxiter--; in mesh_generateid()
985 vap->iv_stats.is_mesh_rtaddfailed++; in mesh_checkpseq()
990 rt->rt_lastmseq = seq; in mesh_checkpseq()
993 if (IEEE80211_MESH_SEQ_GEQ(rt->rt_lastmseq, seq)) { in mesh_checkpseq()
996 rt->rt_lastmseq = seq; in mesh_checkpseq()
1013 if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) { in ieee80211_mesh_find_txnode()
1015 "%s: !valid, flags 0x%x", __func__, rt->rt_flags); in ieee80211_mesh_find_txnode()
1019 if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) { in ieee80211_mesh_find_txnode()
1020 rt = ieee80211_mesh_rt_find(vap, rt->rt_mesh_gate); in ieee80211_mesh_find_txnode()
1022 if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) { in ieee80211_mesh_find_txnode()
1025 rt->rt_flags); in ieee80211_mesh_find_txnode()
1030 return ieee80211_find_txnode(vap, rt->rt_nexthop); in ieee80211_mesh_find_txnode()
1037 struct ifnet *ifp = vap->iv_ifp; in mesh_transmit_to_gate()
1040 IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic); in mesh_transmit_to_gate()
1042 ni = ieee80211_mesh_find_txnode(vap, rt_gate->rt_dest); in mesh_transmit_to_gate()
1070 struct ieee80211com *ic = vap->iv_ic; in ieee80211_mesh_forward_to_gates()
1071 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_forward_to_gates() local
1078 KASSERT( rt_dest->rt_flags == IEEE80211_MESHRT_FLAGS_DISCOVER, in ieee80211_mesh_forward_to_gates()
1082 MESH_RT_LOCK(ms); in ieee80211_mesh_forward_to_gates()
1084 m = ieee80211_ageq_remove(&ic->ic_stageq, in ieee80211_mesh_forward_to_gates()
1086 ieee80211_mac_hash(ic, rt_dest->rt_dest)); in ieee80211_mesh_forward_to_gates()
1088 TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, gr_next) { in ieee80211_mesh_forward_to_gates()
1089 rt_gate = gr->gr_route; in ieee80211_mesh_forward_to_gates()
1092 rt_dest->rt_dest, in ieee80211_mesh_forward_to_gates()
1094 gr->gr_addr, ":"); in ieee80211_mesh_forward_to_gates()
1097 if ((rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) in ieee80211_mesh_forward_to_gates()
1099 KASSERT(rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_GATE, in ieee80211_mesh_forward_to_gates()
1101 KASSERT((rt_gate->rt_flags & in ieee80211_mesh_forward_to_gates()
1109 rt_dest->rt_flags = IEEE80211_MESHRT_FLAGS_PROXY | in ieee80211_mesh_forward_to_gates()
1111 rt_dest->rt_ext_seq = 1; /* random value */ in ieee80211_mesh_forward_to_gates()
1112 IEEE80211_ADDR_COPY(rt_dest->rt_mesh_gate, rt_gate->rt_dest); in ieee80211_mesh_forward_to_gates()
1113 IEEE80211_ADDR_COPY(rt_dest->rt_nexthop, rt_gate->rt_nexthop); in ieee80211_mesh_forward_to_gates()
1114 rt_dest->rt_metric = rt_gate->rt_metric; in ieee80211_mesh_forward_to_gates()
1115 rt_dest->rt_nhops = rt_gate->rt_nhops; in ieee80211_mesh_forward_to_gates()
1116 ieee80211_mesh_rt_update(rt_dest, ms->ms_ppath->mpp_inact); in ieee80211_mesh_forward_to_gates()
1117 MESH_RT_UNLOCK(ms); in ieee80211_mesh_forward_to_gates()
1121 next = mcopy->m_nextpkt; in ieee80211_mesh_forward_to_gates()
1122 mcopy->m_nextpkt = NULL; in ieee80211_mesh_forward_to_gates()
1124 rt_dest->rt_dest, in ieee80211_mesh_forward_to_gates()
1126 mcopy->m_pkthdr.len); in ieee80211_mesh_forward_to_gates()
1129 MESH_RT_LOCK(ms); in ieee80211_mesh_forward_to_gates()
1131 rt_dest->rt_flags = 0; /* Mark invalid */ in ieee80211_mesh_forward_to_gates()
1133 MESH_RT_UNLOCK(ms); in ieee80211_mesh_forward_to_gates()
1144 struct ieee80211com *ic = vap->iv_ic; in mesh_forward()
1145 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_forward() local
1146 struct ifnet *ifp = vap->iv_ifp; in mesh_forward()
1155 /* This is called from the RX path - don't hold this lock */ in mesh_forward()
1163 if (mc->mc_ttl < 1) { in mesh_forward()
1166 vap->iv_stats.is_mesh_fwd_ttl++; in mesh_forward()
1169 if (!(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) { in mesh_forward()
1172 vap->iv_stats.is_mesh_fwd_disabled++; in mesh_forward()
1179 vap->iv_stats.is_mesh_fwd_nobuf++; in mesh_forward()
1188 vap->iv_stats.is_mesh_fwd_tooshort++; in mesh_forward()
1197 whcopy->i_fc[1] &= ~IEEE80211_FC1_RETRY; in mesh_forward()
1198 IEEE80211_ADDR_COPY(whcopy->i_addr2, vap->iv_myaddr); in mesh_forward()
1199 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { in mesh_forward()
1200 ni = ieee80211_ref_node(vap->iv_bss); in mesh_forward()
1201 mcopy->m_flags |= M_MCAST; in mesh_forward()
1203 ni = ieee80211_mesh_find_txnode(vap, whcopy->i_addr3); in mesh_forward()
1213 ms->ms_ppath->mpp_senderror(vap, whcopy->i_addr3, NULL, in mesh_forward()
1215 vap->iv_stats.is_mesh_fwd_nopath++; in mesh_forward()
1219 IEEE80211_ADDR_COPY(whcopy->i_addr1, ni->ni_macaddr); in mesh_forward()
1221 KASSERT(mccopy->mc_ttl > 0, ("%s called with wrong ttl", __func__)); in mesh_forward()
1222 mccopy->mc_ttl--; in mesh_forward()
1228 MPASS((mcopy->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0); in mesh_forward()
1229 mcopy->m_pkthdr.rcvif = (void *) ni; in mesh_forward()
1239 * to do here; we'll have to re-think this soon. in mesh_forward()
1251 #define WHDIR(wh) ((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) in mesh_decap()
1261 if (m->m_len < hdrlen + sizeof(*llc) && in mesh_decap()
1265 vap->iv_stats.is_rx_tooshort++; in mesh_decap()
1270 mc = (const struct ieee80211_meshcntl_ae10 *)&b[hdrlen - meshdrlen]; in mesh_decap()
1273 ("bogus dir, fc 0x%x:0x%x", wh->i_fc[0], wh->i_fc[1])); in mesh_decap()
1276 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && in mesh_decap()
1277 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && in mesh_decap()
1278 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 && in mesh_decap()
1280 !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) || in mesh_decap()
1281 llc->llc_snap.ether_type == htons(ETHERTYPE_IPX))) { in mesh_decap()
1282 m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); in mesh_decap()
1285 m_adj(m, hdrlen - sizeof(*eh)); in mesh_decap()
1288 ae = mc->mc_flags & IEEE80211_MESH_AE_MASK; in mesh_decap()
1290 IEEE80211_ADDR_COPY(eh->ether_dhost, wh->i_addr1); in mesh_decap()
1292 IEEE80211_ADDR_COPY(eh->ether_shost, wh->i_addr3); in mesh_decap()
1294 IEEE80211_ADDR_COPY(eh->ether_shost, in mesh_decap()
1295 MC01(mc)->mc_addr4); in mesh_decap()
1300 vap->iv_stats.is_mesh_badae++; in mesh_decap()
1306 IEEE80211_ADDR_COPY(eh->ether_dhost, wh->i_addr3); in mesh_decap()
1307 IEEE80211_ADDR_COPY(eh->ether_shost, wh->i_addr4); in mesh_decap()
1309 IEEE80211_ADDR_COPY(eh->ether_dhost, mc->mc_addr5); in mesh_decap()
1310 IEEE80211_ADDR_COPY(eh->ether_shost, mc->mc_addr6); in mesh_decap()
1315 vap->iv_stats.is_mesh_badae++; in mesh_decap()
1329 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); in mesh_decap()
1337 * Return non-zero if the unicast mesh data frame should be processed
1345 int ae = mc->mc_flags & 3; in mesh_isucastforme()
1347 KASSERT((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS, in mesh_isucastforme()
1348 ("bad dir 0x%x:0x%x", wh->i_fc[0], wh->i_fc[1])); in mesh_isucastforme()
1355 ieee80211_mesh_rt_find(vap, mc10->mc_addr5); in mesh_isucastforme()
1358 (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY)); in mesh_isucastforme()
1360 return IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_myaddr); in mesh_isucastforme()
1374 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_recv_indiv_data_to_fwrd() local
1377 /* This is called from the RX path - don't hold this lock */ in mesh_recv_indiv_data_to_fwrd()
1378 IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic); in mesh_recv_indiv_data_to_fwrd()
1385 * o lifetime of precursor of addr3 (addr2) is max(init, curr) in mesh_recv_indiv_data_to_fwrd()
1386 * o lifetime of precursor of addr4 (nexthop) is max(init, curr) in mesh_recv_indiv_data_to_fwrd()
1390 rt_meshda = ieee80211_mesh_rt_find(vap, qwh->i_addr3); in mesh_recv_indiv_data_to_fwrd()
1392 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, qwh->i_addr2, in mesh_recv_indiv_data_to_fwrd()
1393 "no route to meshDA(%6D)", qwh->i_addr3, ":"); in mesh_recv_indiv_data_to_fwrd()
1401 return (-1); in mesh_recv_indiv_data_to_fwrd()
1405 ms->ms_ppath->mpp_inact)); in mesh_recv_indiv_data_to_fwrd()
1408 rt_meshsa = ieee80211_mesh_rt_find(vap, qwh->i_addr4); in mesh_recv_indiv_data_to_fwrd()
1411 ms->ms_ppath->mpp_inact)); in mesh_recv_indiv_data_to_fwrd()
1432 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_recv_indiv_data_to_me() local
1436 /* This is called from the RX path - don't hold this lock */ in mesh_recv_indiv_data_to_me()
1437 IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic); in mesh_recv_indiv_data_to_me()
1445 * o lifetime of precursor entry is max(init, curr) in mesh_recv_indiv_data_to_me()
1449 rt = ieee80211_mesh_rt_find(vap, qwh->i_addr4); in mesh_recv_indiv_data_to_me()
1451 ieee80211_mesh_rt_update(rt, ticks_to_msecs(ms->ms_ppath->mpp_inact)); in mesh_recv_indiv_data_to_me()
1454 ae = mc10->mc_flags & IEEE80211_MESH_AE_MASK; in mesh_recv_indiv_data_to_me()
1458 if (IEEE80211_ADDR_EQ(mc10->mc_addr5, qwh->i_addr3)) { in mesh_recv_indiv_data_to_me()
1462 rt = ieee80211_mesh_rt_find(vap, mc10->mc_addr5); in mesh_recv_indiv_data_to_me()
1464 (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) && in mesh_recv_indiv_data_to_me()
1465 (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) == 0) { in mesh_recv_indiv_data_to_me()
1467 * Forward on another mesh-path, according to in mesh_recv_indiv_data_to_me()
1470 IEEE80211_ADDR_COPY(qwh->i_addr3, mc10->mc_addr5); in mesh_recv_indiv_data_to_me()
1479 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_OUTPUT, qwh->i_addr2, in mesh_recv_indiv_data_to_me()
1481 mc10->mc_addr6, ":", mc10->mc_addr5, ":"); in mesh_recv_indiv_data_to_me()
1499 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_recv_group_data() local
1501 /* This is called from the RX path - don't hold this lock */ in mesh_recv_group_data()
1502 IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic); in mesh_recv_group_data()
1506 if(mc->mc_ttl > 0) { in mesh_recv_group_data()
1507 if (mc->mc_flags & IEEE80211_MESH_AE_01) { in mesh_recv_group_data()
1514 if (ms->ms_flags & IEEE80211_MESHFLAGS_GATE && in mesh_recv_group_data()
1515 ms->ms_flags & IEEE80211_MESHFLAGS_FWD) { in mesh_recv_group_data()
1517 MC01(mc)->mc_addr4, "%s", in mesh_recv_group_data()
1532 struct ieee80211vap *vap = ni->ni_vap; in mesh_input()
1533 struct ieee80211com *ic = ni->ni_ic; in mesh_input()
1534 struct ifnet *ifp = vap->iv_ifp; in mesh_input()
1544 ni->ni_inact = ni->ni_inact_reload; in mesh_input()
1547 type = -1; /* undefined */ in mesh_input()
1549 /* This is called from the RX path - don't hold this lock */ in mesh_input()
1552 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { in mesh_input()
1554 ni->ni_macaddr, NULL, in mesh_input()
1555 "too short (1): len %u", m->m_pkthdr.len); in mesh_input()
1556 vap->iv_stats.is_rx_tooshort++; in mesh_input()
1560 * Bit of a cheat here, we use a pointer for a 3-address in mesh_input()
1569 ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]); in mesh_input()
1570 vap->iv_stats.is_rx_badversion++; in mesh_input()
1573 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; in mesh_input()
1574 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; in mesh_input()
1575 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; in mesh_input()
1576 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { in mesh_input()
1577 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); in mesh_input()
1578 ni->ni_noise = nf; in mesh_input()
1584 ic->ic_wme.wme_hipri_traffic++; in mesh_input()
1585 if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1, rxs)) in mesh_input()
1597 if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) { in mesh_input()
1600 vap->iv_stats.is_rx_acl++; in mesh_input()
1606 if (ni == vap->iv_bss) in mesh_input()
1608 if (ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) { in mesh_input()
1610 ni->ni_macaddr, NULL, in mesh_input()
1612 ni->ni_mlstate); in mesh_input()
1613 vap->iv_stats.is_mesh_nolink++; in mesh_input()
1620 vap->iv_stats.is_rx_wrongdir++; in mesh_input()
1628 vap->iv_stats.is_rx_badsubtype++; in mesh_input()
1635 * Mesh Control field is not present in sub-sequent in mesh_input()
1639 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { in mesh_input()
1663 * an unfragmented MSDU, an A-MSDU, or the first in mesh_input()
1669 ni->ni_macaddr, NULL, in mesh_input()
1671 vap->iv_stats.is_rx_elem_missing++; /* XXX: kinda */ in mesh_input()
1676 if (m->m_len < hdrspace + sizeof(struct ieee80211_meshcntl) && in mesh_input()
1680 ni->ni_macaddr, NULL, in mesh_input()
1682 vap->iv_stats.is_rx_tooshort++; in mesh_input()
1692 ae = mc->mc_flags & IEEE80211_MESH_AE_MASK; in mesh_input()
1699 (m->m_len < hdrspace) && in mesh_input()
1702 ni->ni_macaddr, NULL, in mesh_input()
1704 vap->iv_stats.is_rx_tooshort++; in mesh_input()
1709 seq = le32dec(mc->mc_seq); in mesh_input()
1710 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) in mesh_input()
1711 addr = wh->i_addr3; in mesh_input()
1713 addr = MC01(mc)->mc_addr4; in mesh_input()
1715 addr = ((struct ieee80211_qosframe_addr4 *)wh)->i_addr4; in mesh_input()
1716 if (IEEE80211_ADDR_EQ(vap->iv_myaddr, addr)) { in mesh_input()
1719 vap->iv_stats.is_rx_wrongbss++; /* XXX kinda */ in mesh_input()
1723 vap->iv_stats.is_rx_dup++; in mesh_input()
1728 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { in mesh_input()
1729 if (IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr3)) in mesh_input()
1732 else if (IEEE80211_IS_MULTICAST(wh->i_addr3)) in mesh_input()
1759 ni->ni_macaddr, "data", "%s", "decap error"); in mesh_input()
1760 vap->iv_stats.is_rx_decap++; in mesh_input()
1772 vap->iv_stats.is_rx_mgmt++; in mesh_input()
1777 vap->iv_stats.is_rx_wrongdir++; in mesh_input()
1780 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { in mesh_input()
1782 ni->ni_macaddr, "mgt", "too short: len %u", in mesh_input()
1783 m->m_pkthdr.len); in mesh_input()
1784 vap->iv_stats.is_rx_tooshort++; in mesh_input()
1789 (vap->iv_ic->ic_flags & IEEE80211_F_SCAN)) || in mesh_input()
1794 ether_sprintf(wh->i_addr2), rssi); in mesh_input()
1800 vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ in mesh_input()
1803 vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf); in mesh_input()
1806 vap->iv_stats.is_rx_ctl++; in mesh_input()
1832 struct ieee80211vap *vap = ni->ni_vap; in mesh_recv_mgmt()
1833 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_recv_mgmt() local
1834 struct ieee80211com *ic = ni->ni_ic; in mesh_recv_mgmt()
1835 struct ieee80211_channel *rxchan = ic->ic_curchan; in mesh_recv_mgmt()
1842 efrm = mtod(m0, uint8_t *) + m0->m_len; in mesh_recv_mgmt()
1864 vap->iv_stats.is_rx_beacon++; /* XXX remove */ in mesh_recv_mgmt()
1871 if (ic->ic_flags & IEEE80211_F_SCAN) { in mesh_recv_mgmt()
1872 if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) { in mesh_recv_mgmt()
1882 ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; in mesh_recv_mgmt()
1890 if (vap->iv_state != IEEE80211_S_RUN) in mesh_recv_mgmt()
1893 * Ignore non-mesh STAs. in mesh_recv_mgmt()
1900 vap->iv_stats.is_mesh_wrongmesh++; in mesh_recv_mgmt()
1906 if (memcmp(scan.meshid+2, ms->ms_id, ms->ms_idlen) != 0 || in mesh_recv_mgmt()
1910 vap->iv_stats.is_mesh_wrongmesh++; in mesh_recv_mgmt()
1916 if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) { in mesh_recv_mgmt()
1919 vap->iv_stats.is_rx_acl++; in mesh_recv_mgmt()
1925 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { in mesh_recv_mgmt()
1934 if (ni != vap->iv_bss && in mesh_recv_mgmt()
1935 (ms->ms_flags & IEEE80211_MESHFLAGS_AP)) { in mesh_recv_mgmt()
1936 switch (ni->ni_mlstate) { in mesh_recv_mgmt()
1942 if (ni->ni_mlhcnt >= ieee80211_mesh_maxholding) in mesh_recv_mgmt()
1945 ni->ni_mlpid = mesh_generateid(vap); in mesh_recv_mgmt()
1946 if (ni->ni_mlpid == 0) in mesh_recv_mgmt()
1949 args[0] = ni->ni_mlpid; in mesh_recv_mgmt()
1953 ni->ni_mlrcnt = 0; in mesh_recv_mgmt()
1963 rt = ieee80211_mesh_rt_find(vap, wh->i_addr2); in mesh_recv_mgmt()
1967 ms->ms_ppath->mpp_inact)); in mesh_recv_mgmt()
1981 if (vap->iv_state != IEEE80211_S_RUN) { in mesh_recv_mgmt()
1984 ieee80211_state_name[vap->iv_state]); in mesh_recv_mgmt()
1985 vap->iv_stats.is_rx_mgtdiscard++; in mesh_recv_mgmt()
1988 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { in mesh_recv_mgmt()
1992 vap->iv_stats.is_rx_mgtdiscard++; /* XXX stat */ in mesh_recv_mgmt()
2003 while (efrm - frm > 1) { in mesh_recv_mgmt()
2004 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); in mesh_recv_mgmt()
2025 IEEE80211_RATE_MAXSIZE - rates[1], return); in mesh_recv_mgmt()
2030 IEEE80211_VERIFY_SSID(vap->iv_bss, meshid, return); in mesh_recv_mgmt()
2034 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, in mesh_recv_mgmt()
2039 * only a bare-bones rate set, communicate this to in mesh_recv_mgmt()
2042 ieee80211_send_proberesp(vap, wh->i_addr2, 0); in mesh_recv_mgmt()
2048 if (ni == vap->iv_bss) { in mesh_recv_mgmt()
2051 vap->iv_stats.is_rx_mgtdiscard++; in mesh_recv_mgmt()
2052 } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) && in mesh_recv_mgmt()
2053 !IEEE80211_IS_MULTICAST(wh->i_addr1)) { in mesh_recv_mgmt()
2056 vap->iv_stats.is_rx_mgtdiscard++; in mesh_recv_mgmt()
2057 } else if (vap->iv_state != IEEE80211_S_RUN) { in mesh_recv_mgmt()
2060 ieee80211_state_name[vap->iv_state]); in mesh_recv_mgmt()
2061 vap->iv_stats.is_rx_mgtdiscard++; in mesh_recv_mgmt()
2064 (void)ic->ic_recv_action(ni, wh, frm, efrm); in mesh_recv_mgmt()
2079 vap->iv_stats.is_rx_mgtdiscard++; in mesh_recv_mgmt()
2085 vap->iv_stats.is_rx_badsubtype++; in mesh_recv_mgmt()
2110 struct ieee80211vap *vap = ni->ni_vap; in mesh_parse_meshpeering_action()
2117 while (efrm - frm > 1) { in mesh_parse_meshpeering_action()
2118 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return NULL); in mesh_parse_meshpeering_action()
2129 mp->peer_len = mpie->peer_len; in mesh_parse_meshpeering_action()
2130 mp->peer_proto = le16dec(&mpie->peer_proto); in mesh_parse_meshpeering_action()
2131 mp->peer_llinkid = le16dec(&mpie->peer_llinkid); in mesh_parse_meshpeering_action()
2134 mp->peer_linkid = in mesh_parse_meshpeering_action()
2135 le16dec(&mpie->peer_linkid); in mesh_parse_meshpeering_action()
2139 if (mpie->peer_len == in mesh_parse_meshpeering_action()
2141 mp->peer_linkid = 0; in mesh_parse_meshpeering_action()
2142 mp->peer_rcode = in mesh_parse_meshpeering_action()
2143 le16dec(&mpie->peer_linkid); in mesh_parse_meshpeering_action()
2145 mp->peer_linkid = in mesh_parse_meshpeering_action()
2146 le16dec(&mpie->peer_linkid); in mesh_parse_meshpeering_action()
2147 mp->peer_rcode = in mesh_parse_meshpeering_action()
2148 le16dec(&mpie->peer_rcode); in mesh_parse_meshpeering_action()
2198 vap->iv_stats.is_rx_mgtdiscard++; in mesh_parse_meshpeering_action()
2199 switch (ni->ni_mlstate) { in mesh_parse_meshpeering_action()
2208 args[0] = ni->ni_mlpid; in mesh_parse_meshpeering_action()
2209 args[1] = ni->ni_mllid; in mesh_parse_meshpeering_action()
2238 struct ieee80211vap *vap = ni->ni_vap; in mesh_recv_action_meshpeering_open()
2239 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_recv_action_meshpeering_open() local
2253 "recv PEER OPEN, lid 0x%x", meshpeer->peer_llinkid); in mesh_recv_action_meshpeering_open()
2255 switch (ni->ni_mlstate) { in mesh_recv_action_meshpeering_open()
2258 if (ms->ms_neighbors >= IEEE80211_MESH_MAX_NEIGHBORS) { in mesh_recv_action_meshpeering_open()
2259 args[0] = meshpeer->peer_llinkid; in mesh_recv_action_meshpeering_open()
2271 ni->ni_mllid = meshpeer->peer_llinkid; in mesh_recv_action_meshpeering_open()
2272 ni->ni_mlpid = mesh_generateid(vap); in mesh_recv_action_meshpeering_open()
2273 if (ni->ni_mlpid == 0) in mesh_recv_action_meshpeering_open()
2275 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2281 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2282 args[1] = ni->ni_mllid; in mesh_recv_action_meshpeering_open()
2291 if (ni->ni_mllid != meshpeer->peer_llinkid) { in mesh_recv_action_meshpeering_open()
2292 args[0] = ni->ni_mllid; in mesh_recv_action_meshpeering_open()
2293 args[1] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2304 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2305 args[1] = ni->ni_mllid; in mesh_recv_action_meshpeering_open()
2312 ni->ni_mllid = meshpeer->peer_llinkid; in mesh_recv_action_meshpeering_open()
2314 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2315 args[1] = ni->ni_mllid; in mesh_recv_action_meshpeering_open()
2320 /* NB: don't setup/clear any timeout */ in mesh_recv_action_meshpeering_open()
2323 if (ni->ni_mlpid != meshpeer->peer_linkid || in mesh_recv_action_meshpeering_open()
2324 ni->ni_mllid != meshpeer->peer_llinkid) { in mesh_recv_action_meshpeering_open()
2325 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2326 args[1] = ni->ni_mllid; in mesh_recv_action_meshpeering_open()
2338 ni->ni_mllid = meshpeer->peer_llinkid; in mesh_recv_action_meshpeering_open()
2339 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2340 args[1] = ni->ni_mllid; in mesh_recv_action_meshpeering_open()
2348 if (ni->ni_mllid != meshpeer->peer_llinkid) { in mesh_recv_action_meshpeering_open()
2349 args[0] = ni->ni_mllid; in mesh_recv_action_meshpeering_open()
2350 args[1] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2360 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2361 args[1] = ni->ni_mllid; in mesh_recv_action_meshpeering_open()
2368 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_open()
2369 args[1] = meshpeer->peer_llinkid; in mesh_recv_action_meshpeering_open()
2386 struct ieee80211vap *vap = ni->ni_vap; in mesh_recv_action_meshpeering_confirm()
2400 meshpeer->peer_llinkid, meshpeer->peer_linkid); in mesh_recv_action_meshpeering_confirm()
2402 switch (ni->ni_mlstate) { in mesh_recv_action_meshpeering_confirm()
2412 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_confirm()
2413 args[1] = meshpeer->peer_llinkid; in mesh_recv_action_meshpeering_confirm()
2422 if (ni->ni_mllid != meshpeer->peer_llinkid) { in mesh_recv_action_meshpeering_confirm()
2423 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_confirm()
2424 args[1] = ni->ni_mllid; in mesh_recv_action_meshpeering_confirm()
2438 ni->ni_mlstate); in mesh_recv_action_meshpeering_confirm()
2439 vap->iv_stats.is_rx_mgtdiscard++; in mesh_recv_action_meshpeering_confirm()
2467 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, in mesh_recv_action_meshpeering_close()
2470 switch (ni->ni_mlstate) { in mesh_recv_action_meshpeering_close()
2478 args[0] = ni->ni_mlpid; in mesh_recv_action_meshpeering_close()
2479 args[1] = ni->ni_mllid; in mesh_recv_action_meshpeering_close()
2509 if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) { in mesh_recv_action_meshlmetric()
2523 * Returns -1 if parsing fails, otherwise 0.
2530 struct ieee80211vap *vap = ni->ni_vap; in mesh_parse_meshgate_action()
2533 while (efrm - frm > 1) { in mesh_parse_meshgate_action()
2534 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return -1); in mesh_parse_meshgate_action()
2539 ie->gann_ie = gannie->gann_ie; in mesh_parse_meshgate_action()
2540 ie->gann_len = gannie->gann_len; in mesh_parse_meshgate_action()
2541 ie->gann_flags = gannie->gann_flags; in mesh_parse_meshgate_action()
2542 ie->gann_hopcount = gannie->gann_hopcount; in mesh_parse_meshgate_action()
2543 ie->gann_ttl = gannie->gann_ttl; in mesh_parse_meshgate_action()
2544 IEEE80211_ADDR_COPY(ie->gann_addr, gannie->gann_addr); in mesh_parse_meshgate_action()
2545 ie->gann_seq = le32dec(&gannie->gann_seq); in mesh_parse_meshgate_action()
2546 ie->gann_interval = le16dec(&gannie->gann_interval); in mesh_parse_meshgate_action()
2563 struct ieee80211vap *vap = ni->ni_vap; in mesh_recv_action_meshgate()
2564 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_recv_action_meshgate() local
2574 ni->ni_macaddr, NULL, "%s", in mesh_recv_action_meshgate()
2576 vap->iv_stats.is_rx_mgtdiscard++; in mesh_recv_action_meshgate()
2580 if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ie.gann_addr)) in mesh_recv_action_meshgate()
2583 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ni->ni_macaddr, in mesh_recv_action_meshgate()
2587 if (ms == NULL) in mesh_recv_action_meshgate()
2589 MESH_RT_LOCK(ms); in mesh_recv_action_meshgate()
2590 TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, next) { in mesh_recv_action_meshgate()
2591 if (!IEEE80211_ADDR_EQ(gr->gr_addr, ie.gann_addr)) in mesh_recv_action_meshgate()
2593 if (ie.gann_seq <= gr->gr_lastseq) { in mesh_recv_action_meshgate()
2595 ni->ni_macaddr, NULL, in mesh_recv_action_meshgate()
2597 ie.gann_seq, gr->gr_lastseq); in mesh_recv_action_meshgate()
2598 MESH_RT_UNLOCK(ms); in mesh_recv_action_meshgate()
2612 IEEE80211_ADDR_COPY(gr->gr_addr, ie.gann_addr); in mesh_recv_action_meshgate()
2613 TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next); in mesh_recv_action_meshgate()
2615 gr->gr_lastseq = ie.gann_seq; in mesh_recv_action_meshgate()
2618 rt_gate = mesh_rt_find_locked(ms, gr->gr_addr); in mesh_recv_action_meshgate()
2620 rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) { in mesh_recv_action_meshgate()
2621 gr->gr_route = rt_gate; in mesh_recv_action_meshgate()
2622 rt_gate->rt_flags |= IEEE80211_MESHRT_FLAGS_GATE; in mesh_recv_action_meshgate()
2625 MESH_RT_UNLOCK(ms); in mesh_recv_action_meshgate()
2628 if ((ie.gann_ttl - 1) < 1 && !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) in mesh_recv_action_meshgate()
2632 pgann.gann_ttl = ie.gann_ttl - 1; in mesh_recv_action_meshgate()
2640 ieee80211_send_action(vap->iv_bss, IEEE80211_ACTION_CAT_MESH, in mesh_recv_action_meshgate()
2652 struct ieee80211vap *vap = ni->ni_vap; in mesh_send_action()
2653 struct ieee80211com *ic = ni->ni_ic; in mesh_send_action()
2659 if (vap->iv_state == IEEE80211_S_CAC) { in mesh_send_action()
2662 vap->iv_stats.is_tx_badstate++; in mesh_send_action()
2678 m->m_flags |= M_ENCAP; /* mark encapsulated */ in mesh_send_action()
2682 params.ibp_rate0 = ni->ni_txparms->mgmtrate; in mesh_send_action()
2686 params.ibp_try0 = ni->ni_txparms->maxretry; in mesh_send_action()
2687 params.ibp_power = ni->ni_txpower; in mesh_send_action()
2713 struct ieee80211vap *vap = ni->ni_vap; in mesh_send_action_meshpeering_open()
2714 struct ieee80211com *ic = ni->ni_ic; in mesh_send_action_meshpeering_open()
2725 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in mesh_send_action_meshpeering_open()
2729 ic->ic_headroom + sizeof(struct ieee80211_frame), in mesh_send_action_meshpeering_open()
2733 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) in mesh_send_action_meshpeering_open()
2752 ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan)); in mesh_send_action_meshpeering_open()
2753 rs = ieee80211_get_suprates(ic, ic->ic_curchan); in mesh_send_action_meshpeering_open()
2760 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in mesh_send_action_meshpeering_open()
2761 return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m); in mesh_send_action_meshpeering_open()
2763 vap->iv_stats.is_tx_nobuf++; in mesh_send_action_meshpeering_open()
2773 struct ieee80211vap *vap = ni->ni_vap; in mesh_send_action_meshpeering_confirm()
2774 struct ieee80211com *ic = ni->ni_ic; in mesh_send_action_meshpeering_confirm()
2786 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in mesh_send_action_meshpeering_confirm()
2790 ic->ic_headroom + sizeof(struct ieee80211_frame), in mesh_send_action_meshpeering_confirm()
2796 + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) in mesh_send_action_meshpeering_confirm()
2817 ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan)); in mesh_send_action_meshpeering_confirm()
2820 rs = ieee80211_get_suprates(ic, ic->ic_curchan); in mesh_send_action_meshpeering_confirm()
2828 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in mesh_send_action_meshpeering_confirm()
2829 return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m); in mesh_send_action_meshpeering_confirm()
2831 vap->iv_stats.is_tx_nobuf++; in mesh_send_action_meshpeering_confirm()
2841 struct ieee80211vap *vap = ni->ni_vap; in mesh_send_action_meshpeering_close()
2842 struct ieee80211com *ic = ni->ni_ic; in mesh_send_action_meshpeering_close()
2853 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in mesh_send_action_meshpeering_close()
2857 ic->ic_headroom + sizeof(struct ieee80211_frame), in mesh_send_action_meshpeering_close()
2877 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in mesh_send_action_meshpeering_close()
2878 return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m); in mesh_send_action_meshpeering_close()
2880 vap->iv_stats.is_tx_nobuf++; in mesh_send_action_meshpeering_close()
2890 struct ieee80211vap *vap = ni->ni_vap; in mesh_send_action_meshlmetric()
2891 struct ieee80211com *ic = ni->ni_ic; in mesh_send_action_meshlmetric()
2896 if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) { in mesh_send_action_meshlmetric()
2902 ie->lm_metric); in mesh_send_action_meshlmetric()
2906 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in mesh_send_action_meshlmetric()
2910 ic->ic_headroom + sizeof(struct ieee80211_frame), in mesh_send_action_meshlmetric()
2924 ie->lm_flags, ie->lm_metric); in mesh_send_action_meshlmetric()
2925 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in mesh_send_action_meshlmetric()
2926 return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m); in mesh_send_action_meshlmetric()
2928 vap->iv_stats.is_tx_nobuf++; in mesh_send_action_meshlmetric()
2938 struct ieee80211vap *vap = ni->ni_vap; in mesh_send_action_meshgate()
2939 struct ieee80211com *ic = ni->ni_ic; in mesh_send_action_meshgate()
2946 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in mesh_send_action_meshgate()
2950 ic->ic_headroom + sizeof(struct ieee80211_frame), in mesh_send_action_meshgate()
2964 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in mesh_send_action_meshgate()
2965 return mesh_send_action(ni, vap->iv_myaddr, broadcastaddr, m); in mesh_send_action_meshgate()
2967 vap->iv_stats.is_tx_nobuf++; in mesh_send_action_meshgate()
2976 switch (ni->ni_mlstate) { in mesh_peer_timeout_setup()
2978 ni->ni_mltval = ieee80211_mesh_holdingtimeout; in mesh_peer_timeout_setup()
2981 ni->ni_mltval = ieee80211_mesh_confirmtimeout; in mesh_peer_timeout_setup()
2984 ni->ni_mltval = 0; in mesh_peer_timeout_setup()
2987 ni->ni_mltval = ieee80211_mesh_retrytimeout; in mesh_peer_timeout_setup()
2990 if (ni->ni_mltval) in mesh_peer_timeout_setup()
2991 callout_reset(&ni->ni_mltimer, ni->ni_mltval, in mesh_peer_timeout_setup()
3004 ni->ni_mltval += r % ni->ni_mltval; in mesh_peer_timeout_backoff()
3005 callout_reset(&ni->ni_mltimer, ni->ni_mltval, mesh_peer_timeout_cb, in mesh_peer_timeout_backoff()
3012 callout_drain(&ni->ni_mltimer); in mesh_peer_timeout_stop()
3020 /* After backoff timeout, try to peer automatically again. */ in mesh_peer_backoff_cb()
3021 ni->ni_mlhcnt = 0; in mesh_peer_backoff_cb()
3025 * Mesh Peer Link Management FSM timeout handling.
3033 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_MESH, in mesh_peer_timeout_cb()
3034 ni, "mesh link timeout, state %d, retry counter %d", in mesh_peer_timeout_cb()
3035 ni->ni_mlstate, ni->ni_mlrcnt); in mesh_peer_timeout_cb()
3037 switch (ni->ni_mlstate) { in mesh_peer_timeout_cb()
3043 if (ni->ni_mlrcnt == ieee80211_mesh_maxretries) { in mesh_peer_timeout_cb()
3044 args[0] = ni->ni_mlpid; in mesh_peer_timeout_cb()
3049 ni->ni_mlrcnt = 0; in mesh_peer_timeout_cb()
3053 args[0] = ni->ni_mlpid; in mesh_peer_timeout_cb()
3057 ni->ni_mlrcnt++; in mesh_peer_timeout_cb()
3062 args[0] = ni->ni_mlpid; in mesh_peer_timeout_cb()
3071 ni->ni_mlhcnt++; in mesh_peer_timeout_cb()
3072 if (ni->ni_mlhcnt >= ieee80211_mesh_maxholding) in mesh_peer_timeout_cb()
3073 callout_reset(&ni->ni_mlhtimer, in mesh_peer_timeout_cb()
3084 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_verify_meshid() local
3086 if (ie == NULL || ie[1] != ms->ms_idlen) in mesh_verify_meshid()
3088 return memcmp(ms->ms_id, ie + 2, ms->ms_idlen); in mesh_verify_meshid()
3099 const struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_verify_meshconf() local
3103 if (meshconf->conf_pselid != ms->ms_ppath->mpp_ie) { in mesh_verify_meshconf()
3106 meshconf->conf_pselid); in mesh_verify_meshconf()
3109 if (meshconf->conf_pmetid != ms->ms_pmetric->mpm_ie) { in mesh_verify_meshconf()
3112 meshconf->conf_pmetid); in mesh_verify_meshconf()
3115 if (meshconf->conf_ccid != 0) { in mesh_verify_meshconf()
3118 meshconf->conf_ccid); in mesh_verify_meshconf()
3121 if (meshconf->conf_syncid != IEEE80211_MESHCONF_SYNC_NEIGHOFF) { in mesh_verify_meshconf()
3124 meshconf->conf_syncid); in mesh_verify_meshconf()
3127 if (meshconf->conf_authid != 0) { in mesh_verify_meshconf()
3130 meshconf->conf_pselid); in mesh_verify_meshconf()
3134 if (!(meshconf->conf_cap & IEEE80211_MESHCONF_CAP_AP)) { in mesh_verify_meshconf()
3136 "not accepting peers: 0x%x\n", meshconf->conf_cap); in mesh_verify_meshconf()
3150 meshpeer->peer_len < IEEE80211_MPM_BASE_SZ || in mesh_verify_meshpeer()
3151 meshpeer->peer_len > IEEE80211_MPM_MAX_SZ) in mesh_verify_meshpeer()
3153 if (meshpeer->peer_proto != IEEE80211_MPPID_MPM) { in mesh_verify_meshpeer()
3157 meshpeer->peer_proto); in mesh_verify_meshpeer()
3162 if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ) in mesh_verify_meshpeer()
3166 if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ + 2) in mesh_verify_meshpeer()
3170 if (meshpeer->peer_len < IEEE80211_MPM_BASE_SZ + 2) in mesh_verify_meshpeer()
3172 if (meshpeer->peer_len == (IEEE80211_MPM_BASE_SZ + 2) && in mesh_verify_meshpeer()
3173 meshpeer->peer_linkid != 0) in mesh_verify_meshpeer()
3175 if (meshpeer->peer_rcode == 0) in mesh_verify_meshpeer()
3188 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_add_meshid() local
3190 KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a mbss vap")); in ieee80211_add_meshid()
3193 *frm++ = ms->ms_idlen; in ieee80211_add_meshid()
3194 memcpy(frm, ms->ms_id, ms->ms_idlen); in ieee80211_add_meshid()
3195 return frm + ms->ms_idlen; in ieee80211_add_meshid()
3206 const struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_add_meshconf() local
3209 KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap")); in ieee80211_add_meshconf()
3213 *frm++ = ms->ms_ppath->mpp_ie; /* path selection */ in ieee80211_add_meshconf()
3214 *frm++ = ms->ms_pmetric->mpm_ie; /* link metric */ in ieee80211_add_meshconf()
3219 *frm = (ms->ms_neighbors > IEEE80211_MESH_MAX_NEIGHBORS ? in ieee80211_add_meshconf()
3220 IEEE80211_MESH_MAX_NEIGHBORS : ms->ms_neighbors) << 1; in ieee80211_add_meshconf()
3221 if (ms->ms_flags & IEEE80211_MESHFLAGS_GATE) in ieee80211_add_meshconf()
3225 if (ms->ms_flags & IEEE80211_MESHFLAGS_AP) in ieee80211_add_meshconf()
3227 if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) in ieee80211_add_meshconf()
3278 * Max 802.11s overhead.
3295 struct ieee80211com *ic = ni->ni_ic; in mesh_airtime_calc()
3296 struct ifnet *ifp = ni->ni_vap->iv_ifp; in mesh_airtime_calc()
3303 overhead = ieee80211_compute_duration(ic->ic_rt, in mesh_airtime_calc()
3311 ((1 << S_FACTOR) / ((1 << M_BITS) - errrate)); in mesh_airtime_calc()
3339 *frm++ = ie->gann_flags; in ieee80211_add_meshgate()
3340 *frm++ = ie->gann_hopcount; in ieee80211_add_meshgate()
3341 *frm++ = ie->gann_ttl; in ieee80211_add_meshgate()
3342 IEEE80211_ADDR_COPY(frm, ie->gann_addr); in ieee80211_add_meshgate()
3344 ADDWORD(frm, ie->gann_seq); in ieee80211_add_meshgate()
3345 ADDSHORT(frm, ie->gann_interval); in ieee80211_add_meshgate()
3352 * Initialize any mesh-specific node state.
3357 ni->ni_flags |= IEEE80211_NODE_QOS; in ieee80211_mesh_node_init()
3358 callout_init(&ni->ni_mltimer, 1); in ieee80211_mesh_node_init()
3359 callout_init(&ni->ni_mlhtimer, 1); in ieee80211_mesh_node_init()
3363 * Cleanup any mesh-specific node state.
3368 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_mesh_node_cleanup()
3369 struct ieee80211_mesh_state *ms = vap->iv_mesh; in ieee80211_mesh_node_cleanup() local
3371 callout_drain(&ni->ni_mltimer); in ieee80211_mesh_node_cleanup()
3372 callout_drain(&ni->ni_mlhtimer); in ieee80211_mesh_node_cleanup()
3373 /* NB: short-circuit callbacks after mesh_vdetach */ in ieee80211_mesh_node_cleanup()
3374 if (vap->iv_mesh != NULL) in ieee80211_mesh_node_cleanup()
3375 ms->ms_ppath->mpp_peerdown(ni); in ieee80211_mesh_node_cleanup()
3381 ni->ni_meshidlen = ie[1]; in ieee80211_parse_meshid()
3382 memcpy(ni->ni_meshid, ie + 2, ie[1]); in ieee80211_parse_meshid()
3386 * Setup mesh-specific node state on neighbor discovery.
3393 ieee80211_parse_meshid(ni, sp->meshid); in ieee80211_mesh_init_neighbor()
3400 KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap")); in ieee80211_mesh_update_beacon()
3402 if (isset(bo->bo_flags, IEEE80211_BEACON_MESHCONF)) { in ieee80211_mesh_update_beacon()
3403 (void)ieee80211_add_meshconf(bo->bo_meshconf, vap); in ieee80211_mesh_update_beacon()
3404 clrbit(bo->bo_flags, IEEE80211_BEACON_MESHCONF); in ieee80211_mesh_update_beacon()
3411 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_ioctl_get80211() local
3419 if (vap->iv_opmode != IEEE80211_M_MBSS) in mesh_ioctl_get80211()
3423 switch (ireq->i_type) { in mesh_ioctl_get80211()
3425 ireq->i_len = ms->ms_idlen; in mesh_ioctl_get80211()
3426 memcpy(tmpmeshid, ms->ms_id, ireq->i_len); in mesh_ioctl_get80211()
3427 error = copyout(tmpmeshid, ireq->i_data, ireq->i_len); in mesh_ioctl_get80211()
3430 ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_AP) != 0; in mesh_ioctl_get80211()
3433 ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) != 0; in mesh_ioctl_get80211()
3436 ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_GATE) != 0; in mesh_ioctl_get80211()
3439 ireq->i_val = ms->ms_ttl; in mesh_ioctl_get80211()
3442 switch (ireq->i_val) { in mesh_ioctl_get80211()
3445 MESH_RT_LOCK(ms); in mesh_ioctl_get80211()
3446 TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) { in mesh_ioctl_get80211()
3449 MESH_RT_UNLOCK(ms); in mesh_ioctl_get80211()
3450 if (len > ireq->i_len || ireq->i_len < sizeof(*imr)) { in mesh_ioctl_get80211()
3451 ireq->i_len = len; in mesh_ioctl_get80211()
3454 ireq->i_len = len; in mesh_ioctl_get80211()
3461 MESH_RT_LOCK(ms); in mesh_ioctl_get80211()
3462 TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) { in mesh_ioctl_get80211()
3467 IEEE80211_ADDR_COPY(imr->imr_dest, in mesh_ioctl_get80211()
3468 rt->rt_dest); in mesh_ioctl_get80211()
3469 IEEE80211_ADDR_COPY(imr->imr_nexthop, in mesh_ioctl_get80211()
3470 rt->rt_nexthop); in mesh_ioctl_get80211()
3471 imr->imr_metric = rt->rt_metric; in mesh_ioctl_get80211()
3472 imr->imr_nhops = rt->rt_nhops; in mesh_ioctl_get80211()
3473 imr->imr_lifetime = in mesh_ioctl_get80211()
3475 imr->imr_lastmseq = rt->rt_lastmseq; in mesh_ioctl_get80211()
3476 imr->imr_flags = rt->rt_flags; /* last */ in mesh_ioctl_get80211()
3479 MESH_RT_UNLOCK(ms); in mesh_ioctl_get80211()
3480 error = copyout(p, (uint8_t *)ireq->i_data, in mesh_ioctl_get80211()
3481 ireq->i_len); in mesh_ioctl_get80211()
3493 len = strlen(ms->ms_pmetric->mpm_descr); in mesh_ioctl_get80211()
3494 if (ireq->i_len < len) in mesh_ioctl_get80211()
3496 ireq->i_len = len; in mesh_ioctl_get80211()
3497 error = copyout(ms->ms_pmetric->mpm_descr, in mesh_ioctl_get80211()
3498 (uint8_t *)ireq->i_data, len); in mesh_ioctl_get80211()
3501 len = strlen(ms->ms_ppath->mpp_descr); in mesh_ioctl_get80211()
3502 if (ireq->i_len < len) in mesh_ioctl_get80211()
3504 ireq->i_len = len; in mesh_ioctl_get80211()
3505 error = copyout(ms->ms_ppath->mpp_descr, in mesh_ioctl_get80211()
3506 (uint8_t *)ireq->i_data, len); in mesh_ioctl_get80211()
3519 struct ieee80211_mesh_state *ms = vap->iv_mesh; in mesh_ioctl_set80211() local
3525 if (vap->iv_opmode != IEEE80211_M_MBSS) in mesh_ioctl_set80211()
3529 switch (ireq->i_type) { in mesh_ioctl_set80211()
3531 if (ireq->i_val != 0 || ireq->i_len > IEEE80211_MESHID_LEN) in mesh_ioctl_set80211()
3533 error = copyin(ireq->i_data, tmpmeshid, ireq->i_len); in mesh_ioctl_set80211()
3536 memset(ms->ms_id, 0, IEEE80211_NWID_LEN); in mesh_ioctl_set80211()
3537 ms->ms_idlen = ireq->i_len; in mesh_ioctl_set80211()
3538 memcpy(ms->ms_id, tmpmeshid, ireq->i_len); in mesh_ioctl_set80211()
3542 if (ireq->i_val) in mesh_ioctl_set80211()
3543 ms->ms_flags |= IEEE80211_MESHFLAGS_AP; in mesh_ioctl_set80211()
3545 ms->ms_flags &= ~IEEE80211_MESHFLAGS_AP; in mesh_ioctl_set80211()
3549 if (ireq->i_val) in mesh_ioctl_set80211()
3550 ms->ms_flags |= IEEE80211_MESHFLAGS_FWD; in mesh_ioctl_set80211()
3552 ms->ms_flags &= ~IEEE80211_MESHFLAGS_FWD; in mesh_ioctl_set80211()
3556 if (ireq->i_val) in mesh_ioctl_set80211()
3557 ms->ms_flags |= IEEE80211_MESHFLAGS_GATE; in mesh_ioctl_set80211()
3559 ms->ms_flags &= ~IEEE80211_MESHFLAGS_GATE; in mesh_ioctl_set80211()
3562 ms->ms_ttl = (uint8_t) ireq->i_val; in mesh_ioctl_set80211()
3565 switch (ireq->i_val) { in mesh_ioctl_set80211()
3572 error = copyin(ireq->i_data, tmpaddr, in mesh_ioctl_set80211()
3576 if (IEEE80211_ADDR_EQ(vap->iv_myaddr, tmpaddr) || in mesh_ioctl_set80211()
3582 error = copyin(ireq->i_data, tmpaddr, in mesh_ioctl_set80211()
3593 error = copyin(ireq->i_data, tmpproto, sizeof(tmpproto)); in mesh_ioctl_set80211()
3601 error = copyin(ireq->i_data, tmpproto, sizeof(tmpproto)); in mesh_ioctl_set80211()