#include "mesh.h"
-#define IEEE80211_FC(type, stype) cpu_to_le16(type | stype)
-
#define TEST_FRAME_LEN 8192
#define MAX_METRIC 0xffffffff
#define ARITH_SHIFT 8
/* Reply and forward */
#define MP_F_RF 0x2
+static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
+{
+ if (ae)
+ offset += 6;
+ return le32_to_cpu(get_unaligned((__le32 *) (preq_elem + offset)));
+}
+
/* HWMP IE processing macros */
-#define AE_F (1<<6)
-#define AE_F_SET(x) (*x & AE_F)
-#define PREQ_IE_FLAGS(x) (*(x))
-#define PREQ_IE_HOPCOUNT(x) (*(x + 1))
-#define PREQ_IE_TTL(x) (*(x + 2))
-#define PREQ_IE_PREQ_ID(x) le32_to_cpu(*((u32 *) (x + 3)))
-#define PREQ_IE_ORIG_ADDR(x) (x + 7)
-#define PREQ_IE_ORIG_DSN(x) le32_to_cpu(*((u32 *) (x + 13)))
-#define PREQ_IE_LIFETIME(x) le32_to_cpu(*((u32 *) \
- (AE_F_SET(x) ? x + 23 : x + 17)))
-#define PREQ_IE_METRIC(x) le32_to_cpu(*((u32 *) \
- (AE_F_SET(x) ? x + 27 : x + 21)))
-#define PREQ_IE_DST_F(x) (*(AE_F_SET(x) ? x + 32 : x + 26))
-#define PREQ_IE_DST_ADDR(x) (AE_F_SET(x) ? x + 33 : x + 27)
-#define PREQ_IE_DST_DSN(x) le32_to_cpu(*((u32 *) \
- (AE_F_SET(x) ? x + 39 : x + 33)))
-
-
-#define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x)
-#define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x)
-#define PREP_IE_TTL(x) PREQ_IE_TTL(x)
-#define PREP_IE_ORIG_ADDR(x) (x + 3)
-#define PREP_IE_ORIG_DSN(x) le32_to_cpu(*((u32 *) (x + 9)))
-#define PREP_IE_LIFETIME(x) le32_to_cpu(*((u32 *) \
- (AE_F_SET(x) ? x + 19 : x + 13)))
-#define PREP_IE_METRIC(x) le32_to_cpu(*((u32 *) \
- (AE_F_SET(x) ? x + 23 : x + 17)))
-#define PREP_IE_DST_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21)
-#define PREP_IE_DST_DSN(x) le32_to_cpu(*((u32 *) \
- (AE_F_SET(x) ? x + 33 : x + 27)))
-
-#define PERR_IE_DST_ADDR(x) (x + 2)
-#define PERR_IE_DST_DSN(x) le32_to_cpu(*((u32 *) (x + 8)))
+#define AE_F (1<<6)
+#define AE_F_SET(x) (*x & AE_F)
+#define PREQ_IE_FLAGS(x) (*(x))
+#define PREQ_IE_HOPCOUNT(x) (*(x + 1))
+#define PREQ_IE_TTL(x) (*(x + 2))
+#define PREQ_IE_PREQ_ID(x) u32_field_get(x, 3, 0)
+#define PREQ_IE_ORIG_ADDR(x) (x + 7)
+#define PREQ_IE_ORIG_DSN(x) u32_field_get(x, 13, 0);
+#define PREQ_IE_LIFETIME(x) u32_field_get(x, 17, AE_F_SET(x));
+#define PREQ_IE_METRIC(x) u32_field_get(x, 21, AE_F_SET(x));
+#define PREQ_IE_DST_F(x) (*(AE_F_SET(x) ? x + 32 : x + 26))
+#define PREQ_IE_DST_ADDR(x) (AE_F_SET(x) ? x + 33 : x + 27)
+#define PREQ_IE_DST_DSN(x) u32_field_get(x, 33, AE_F_SET(x));
+
+
+#define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x)
+#define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x)
+#define PREP_IE_TTL(x) PREQ_IE_TTL(x)
+#define PREP_IE_ORIG_ADDR(x) (x + 3)
+#define PREP_IE_ORIG_DSN(x) u32_field_get(x, 9, 0);
+#define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x));
+#define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x));
+#define PREP_IE_DST_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21)
+#define PREP_IE_DST_DSN(x) u32_field_get(x, 27, AE_F_SET(x));
+
+#define PERR_IE_DST_ADDR(x) (x + 2)
+#define PERR_IE_DST_DSN(x) u32_field_get(x, 8, 0);
#define TU_TO_EXP_TIME(x) (jiffies + msecs_to_jiffies(x * 1024 / 1000))
#define MSEC_TO_TU(x) (x*1000/1024)
*pos++ = WLAN_EID_PREP;
break;
default:
- kfree(skb);
+ kfree_skb(skb);
return -ENOTSUPP;
break;
}
orig_metric = PREP_IE_METRIC(hwmp_ie);
break;
default:
- sta_info_put(sta);
rcu_read_unlock();
return 0;
}
mpath = mesh_path_lookup(orig_addr, dev);
if (!mpath) {
rcu_read_unlock();
- sta_info_put(sta);
return 0;
}
spin_lock_bh(&mpath->state_lock);
mpath = mesh_path_lookup(ta, dev);
if (!mpath) {
rcu_read_unlock();
- sta_info_put(sta);
return 0;
}
spin_lock_bh(&mpath->state_lock);
spin_unlock_bh(&mpath->state_lock);
}
- sta_info_put(sta);
rcu_read_unlock();
return process ? new_metric : 0;
ttl = ifsta->mshcfg.dot11MeshTTL;
if (ttl != 0)
mesh_path_sel_frame_tx(MPATH_PREP, 0, dst_addr,
- __cpu_to_le32(dst_dsn), 0, orig_addr,
- __cpu_to_le32(orig_dsn), mgmt->sa, 0, ttl,
- __cpu_to_le32(lifetime), __cpu_to_le32(metric),
+ cpu_to_le32(dst_dsn), 0, orig_addr,
+ cpu_to_le32(orig_dsn), mgmt->sa, 0, ttl,
+ cpu_to_le32(lifetime), cpu_to_le32(metric),
0, dev);
else
ifsta->mshstats.dropped_frames_ttl++;
preq_id = PREQ_IE_PREQ_ID(preq_elem);
hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
- __cpu_to_le32(orig_dsn), dst_flags, dst_addr,
- __cpu_to_le32(dst_dsn), dev->broadcast,
- hopcount, ttl, __cpu_to_le32(lifetime),
- __cpu_to_le32(metric), __cpu_to_le32(preq_id),
+ cpu_to_le32(orig_dsn), dst_flags, dst_addr,
+ cpu_to_le32(dst_dsn), dev->broadcast,
+ hopcount, ttl, cpu_to_le32(lifetime),
+ cpu_to_le32(metric), cpu_to_le32(preq_id),
dev);
ifsta->mshstats.fwded_frames++;
}
orig_dsn = PREP_IE_ORIG_DSN(prep_elem);
mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
- __cpu_to_le32(orig_dsn), 0, dst_addr,
- __cpu_to_le32(dst_dsn), mpath->next_hop->addr, hopcount, ttl,
- __cpu_to_le32(lifetime), __cpu_to_le32(metric),
+ cpu_to_le32(orig_dsn), 0, dst_addr,
+ cpu_to_le32(dst_dsn), mpath->next_hop->addr, hopcount, ttl,
+ cpu_to_le32(lifetime), cpu_to_le32(metric),
0, dev);
rcu_read_unlock();
sdata->u.sta.mshstats.fwded_frames++;
mpath->flags &= ~MESH_PATH_ACTIVE;
mpath->dsn = dst_dsn;
spin_unlock_bh(&mpath->state_lock);
- mesh_path_error_tx(dst_addr, dst_dsn, dev->broadcast,
- dev);
+ mesh_path_error_tx(dst_addr, cpu_to_le32(dst_dsn),
+ dev->broadcast, dev);
} else
spin_unlock_bh(&mpath->state_lock);
}
spin_unlock_bh(&mpath->state_lock);
mesh_path_sel_frame_tx(MPATH_PREQ, 0, dev->dev_addr,
- __cpu_to_le32(ifsta->dsn), dst_flags, mpath->dst,
- __cpu_to_le32(mpath->dsn), dev->broadcast, 0,
- ttl, __cpu_to_le32(lifetime), 0,
- __cpu_to_le32(ifsta->preq_id++), dev);
+ cpu_to_le32(ifsta->dsn), dst_flags, mpath->dst,
+ cpu_to_le32(mpath->dsn), dev->broadcast, 0,
+ ttl, cpu_to_le32(lifetime), 0,
+ cpu_to_le32(ifsta->preq_id++), dev);
mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
enddiscovery:
{
struct ieee80211_sub_if_data *sdata;
struct mesh_path *mpath;
- bool delete = false;
rcu_read_lock();
mpath = (struct mesh_path *) data;
goto endmpathtimer;
spin_lock_bh(&mpath->state_lock);
sdata = IEEE80211_DEV_TO_SUB_IF(mpath->dev);
- if (mpath->flags & MESH_PATH_DELETE) {
- mpath->flags = 0;
- delete = true;
- } else if (mpath->flags & MESH_PATH_RESOLVED ||
+ if (mpath->flags & MESH_PATH_RESOLVED ||
(!(mpath->flags & MESH_PATH_RESOLVING)))
mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
else if (mpath->discovery_retries < max_preq_retries(sdata)) {
spin_unlock_bh(&mpath->state_lock);
endmpathtimer:
rcu_read_unlock();
- if (delete)
- mesh_path_del(mpath->dst, mpath->dev);
}