10 #include <linux/slab.h>
12 #include <asm/unaligned.h>
16 #define TEST_FRAME_LEN 8192
17 #define MAX_METRIC 0xffffffff
20 #define MAX_PREQ_QUEUE_LEN 64
29 #define MP_F_RCODE 0x02
31 static void mesh_queue_preq(
struct mesh_path *,
u8);
33 static inline u32 u32_field_get(
u8 *preq_elem,
int offset,
bool ae)
40 static inline u32 u16_field_get(
u8 *preq_elem,
int offset,
bool ae)
44 return get_unaligned_le16(preq_elem + offset);
49 #define AE_F_SET(x) (*x & AE_F)
50 #define PREQ_IE_FLAGS(x) (*(x))
51 #define PREQ_IE_HOPCOUNT(x) (*(x + 1))
52 #define PREQ_IE_TTL(x) (*(x + 2))
53 #define PREQ_IE_PREQ_ID(x) u32_field_get(x, 3, 0)
54 #define PREQ_IE_ORIG_ADDR(x) (x + 7)
55 #define PREQ_IE_ORIG_SN(x) u32_field_get(x, 13, 0)
56 #define PREQ_IE_LIFETIME(x) u32_field_get(x, 17, AE_F_SET(x))
57 #define PREQ_IE_METRIC(x) u32_field_get(x, 21, AE_F_SET(x))
58 #define PREQ_IE_TARGET_F(x) (*(AE_F_SET(x) ? x + 32 : x + 26))
59 #define PREQ_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 33 : x + 27)
60 #define PREQ_IE_TARGET_SN(x) u32_field_get(x, 33, AE_F_SET(x))
63 #define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x)
64 #define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x)
65 #define PREP_IE_TTL(x) PREQ_IE_TTL(x)
66 #define PREP_IE_ORIG_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21)
67 #define PREP_IE_ORIG_SN(x) u32_field_get(x, 27, AE_F_SET(x))
68 #define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x))
69 #define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x))
70 #define PREP_IE_TARGET_ADDR(x) (x + 3)
71 #define PREP_IE_TARGET_SN(x) u32_field_get(x, 9, 0)
73 #define PERR_IE_TTL(x) (*(x))
74 #define PERR_IE_TARGET_FLAGS(x) (*(x + 2))
75 #define PERR_IE_TARGET_ADDR(x) (x + 3)
76 #define PERR_IE_TARGET_SN(x) u32_field_get(x, 9, 0)
77 #define PERR_IE_TARGET_RCODE(x) u16_field_get(x, 13, 0)
79 #define MSEC_TO_TU(x) (x*1000/1024)
80 #define SN_GT(x, y) ((s32)(y - x) < 0)
81 #define SN_LT(x, y) ((s32)(x - y) < 0)
83 #define net_traversal_jiffies(s) \
84 msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime)
85 #define default_lifetime(s) \
86 MSEC_TO_TU(s->u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout)
87 #define min_preq_int_jiff(s) \
88 (msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval))
89 #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries)
90 #define disc_timeout_jiff(s) \
91 msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout)
92 #define root_path_confirmation_jiffies(s) \
93 msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval)
102 static const u8 broadcast_addr[
ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
115 sizeof(mgmt->
u.action.u.mesh_action);
133 mgmt->
u.action.u.mesh_action.action_code =
138 mhwmp_dbg(sdata,
"sending PREQ to %pM\n", target);
140 pos =
skb_put(skb, 2 + ie_len);
144 mhwmp_dbg(sdata,
"sending PREP to %pM\n", target);
146 pos =
skb_put(skb, 2 + ie_len);
150 mhwmp_dbg(sdata,
"sending RANN from %pM\n", orig_addr);
152 pos =
skb_put(skb, 2 + ie_len);
167 memcpy(pos, &target_sn, 4);
179 memcpy(pos, &lifetime, 4);
185 *pos++ = target_flags;
188 memcpy(pos, &target_sn, 4);
197 ieee80211_tx_skb(sdata, skb);
209 skb_set_mac_header(skb, 0);
210 skb_set_network_header(skb, 0);
211 skb_set_transport_header(skb, 0);
243 sizeof(mgmt->
u.action.u.mesh_action);
264 mgmt->
u.action.u.mesh_action.action_code =
267 pos =
skb_put(skb, 2 + ie_len);
286 memcpy(pos, &target_sn, 4);
288 memcpy(pos, &target_rcode, 2);
291 prepare_frame_for_deferred_tx(sdata, skb);
293 ifmsh->
mshcfg.dot11MeshHWMPperrMinInterval);
325 u32 tx_time, estimated_retx;
341 tx_time = (device_constant + 10 * test_frame_len /
rate);
343 result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ;
372 u32 orig_sn, orig_metric;
373 unsigned long orig_lifetime, exp_time;
374 u32 last_hop_metric, new_metric;
384 last_hop_metric = airtime_link_metric_get(local, sta);
410 new_metric = orig_metric + last_hop_metric;
411 if (new_metric < orig_metric)
415 if (ether_addr_equal(orig_addr, sdata->
vif.addr)) {
429 if (
SN_GT(mpath->
sn, orig_sn) ||
430 (mpath->
sn == orig_sn &&
431 new_metric >= mpath->
metric)) {
449 mpath->
metric = new_metric;
453 mesh_path_activate(mpath);
465 if (ether_addr_equal(orig_addr, ta))
475 (last_hop_metric > mpath->
metric)))
489 mpath->
metric = last_hop_metric;
492 mesh_path_activate(mpath);
501 return process ? new_metric : 0;
506 u8 *preq_elem,
u32 metric)
513 u32 orig_sn, target_sn, lifetime, orig_metric;
529 mhwmp_dbg(sdata,
"received PREQ from %pM\n", orig_addr);
531 if (ether_addr_equal(target_addr, sdata->
vif.addr)) {
539 target_sn = ++ifmsh->
sn;
542 }
else if (is_broadcast_ether_addr(target_addr) &&
549 target_addr = sdata->
vif.addr;
550 target_sn = ++ifmsh->
sn;
564 mpath->
sn = target_sn;
566 }
else if ((!(target_flags &
MP_F_DO)) &&
570 target_sn = mpath->
sn;
582 ttl = ifmsh->
mshcfg.element_ttl;
584 mhwmp_dbg(sdata,
"replying to the PREQ\n");
585 mesh_path_sel_frame_tx(
MPATH_PREP, 0, orig_addr,
591 ifmsh->
mshstats.dropped_frames_ttl++;
595 if (forward && ifmsh->
mshcfg.dot11MeshForwarding) {
602 ifmsh->
mshstats.dropped_frames_ttl++;
605 mhwmp_dbg(sdata,
"forwarding the PREQ from %pM\n", orig_addr);
609 da = (mpath && mpath->
is_root) ?
615 metric = orig_metric;
618 mesh_path_sel_frame_tx(
MPATH_PREQ, flags, orig_addr,
624 if (!is_multicast_ether_addr(da))
634 next_hop_deref_protected(
struct mesh_path *mpath)
643 u8 *prep_elem,
u32 metric)
650 u32 target_sn, orig_sn, lifetime;
652 mhwmp_dbg(sdata,
"received PREP from %pM\n",
656 if (ether_addr_equal(orig_addr, sdata->
vif.addr))
660 if (!ifmsh->
mshcfg.dot11MeshForwarding)
665 sdata->
u.
mesh.mshstats.dropped_frames_ttl++;
689 mesh_path_sel_frame_tx(
MPATH_PREP, flags, orig_addr,
696 sdata->
u.
mesh.mshstats.fwded_unicast++;
697 sdata->
u.
mesh.mshstats.fwded_frames++;
702 sdata->
u.
mesh.mshstats.dropped_frames_no_route++;
718 ifmsh->
mshstats.dropped_frames_ttl++;
732 sta = next_hop_deref_protected(mpath);
734 ether_addr_equal(ta, sta->
sta.addr) &&
736 SN_GT(target_sn, mpath->
sn))) {
738 mpath->
sn = target_sn;
740 if (!ifmsh->
mshcfg.dot11MeshForwarding)
744 broadcast_addr, sdata);
776 if (ether_addr_equal(orig_addr, sdata->
vif.addr))
780 "received RANN from %pM via neighbour %pM (is_gate=%d)\n",
781 orig_addr, mgmt->
sa, root_is_gate);
790 metric_txsta = airtime_link_metric_get(local, sta);
798 sdata->
u.
mesh.mshstats.dropped_frames_no_route++;
803 if (!(
SN_LT(mpath->
sn, orig_sn)) &&
815 "time to refresh root mpath %pM\n",
832 ifmsh->
mshstats.dropped_frames_ttl++;
838 if (ifmsh->
mshcfg.dot11MeshForwarding) {
839 mesh_path_sel_frame_tx(
MPATH_RANN, flags, orig_addr,
841 0,
NULL, 0, broadcast_addr,
872 baselen = (
u8 *) mgmt->
u.action.u.mesh_action.variable - (
u8 *)
mgmt;
874 len - baselen, &elems);
880 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.
preq,
883 hwmp_preq_frame_process(sdata, mgmt, elems.
preq,
890 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.
prep,
893 hwmp_prep_frame_process(sdata, mgmt, elems.
prep,
900 hwmp_perr_frame_process(sdata, mgmt, elems.
perr);
903 hwmp_rann_frame_process(sdata, mgmt, elems.
rann);
915 static void mesh_queue_preq(
struct mesh_path *mpath,
u8 flags)
923 mhwmp_dbg(sdata,
"could not allocate PREQ node\n");
931 if (printk_ratelimit())
932 mhwmp_dbg(sdata,
"PREQ node queue full\n");
978 u8 ttl, target_flags;
1029 ttl = sdata->
u.
mesh.mshcfg.element_ttl;
1031 sdata->
u.
mesh.mshstats.dropped_frames_ttl++;
1139 ether_addr_equal(sdata->
vif.addr, hdr->
addr4) &&
1158 struct mesh_path *mpath = (
void *) data;
1162 if (sdata->
local->quiescing)
1175 mesh_queue_preq(mpath, 0);
1183 mhwmp_dbg(sdata,
"no gate was reachable\n");
1193 u32 interval = ifmsh->
mshcfg.dot11MeshHWMPRannInterval;
1196 flags = (ifmsh->
mshcfg.dot11MeshGateAnnouncementProtocol)
1199 switch (ifmsh->
mshcfg.dot11MeshHWMPRootMode) {
1203 0,
NULL, 0, broadcast_addr,
1204 0, ifmsh->
mshcfg.element_ttl,
1210 interval = ifmsh->
mshcfg.dot11MeshHWMPactivePathToRootTimeout;
1211 target_flags |= IEEE80211_PREQ_TO_FLAG |
1215 (
u8 *) broadcast_addr, 0, broadcast_addr,
1216 0, ifmsh->
mshcfg.element_ttl,
1221 mhwmp_dbg(sdata,
"Proactive mechanism not supported\n");