aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh_hwmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
-rw-r--r--net/mac80211/mesh_hwmp.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 174040a42887..a7afb2d32def 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -113,20 +113,20 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
113 struct ieee80211_sub_if_data *sdata) 113 struct ieee80211_sub_if_data *sdata)
114{ 114{
115 struct ieee80211_local *local = sdata->local; 115 struct ieee80211_local *local = sdata->local;
116 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 116 struct sk_buff *skb;
117 struct ieee80211_mgmt *mgmt; 117 struct ieee80211_mgmt *mgmt;
118 u8 *pos; 118 u8 *pos, ie_len;
119 int ie_len; 119 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
120 sizeof(mgmt->u.action.u.mesh_action);
120 121
122 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
123 hdr_len +
124 2 + 37); /* max HWMP IE */
121 if (!skb) 125 if (!skb)
122 return -1; 126 return -1;
123 skb_reserve(skb, local->hw.extra_tx_headroom); 127 skb_reserve(skb, local->hw.extra_tx_headroom);
124 /* 25 is the size of the common mgmt part (24) plus the size of the 128 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
125 * common action part (1) 129 memset(mgmt, 0, hdr_len);
126 */
127 mgmt = (struct ieee80211_mgmt *)
128 skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action));
129 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action));
130 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 130 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
131 IEEE80211_STYPE_ACTION); 131 IEEE80211_STYPE_ACTION);
132 132
@@ -240,20 +240,20 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
240 struct ieee80211_sub_if_data *sdata) 240 struct ieee80211_sub_if_data *sdata)
241{ 241{
242 struct ieee80211_local *local = sdata->local; 242 struct ieee80211_local *local = sdata->local;
243 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 243 struct sk_buff *skb;
244 struct ieee80211_mgmt *mgmt; 244 struct ieee80211_mgmt *mgmt;
245 u8 *pos; 245 u8 *pos, ie_len;
246 int ie_len; 246 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
247 sizeof(mgmt->u.action.u.mesh_action);
247 248
249 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
250 hdr_len +
251 2 + 15 /* PERR IE */);
248 if (!skb) 252 if (!skb)
249 return -1; 253 return -1;
250 skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom); 254 skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom);
251 /* 25 is the size of the common mgmt part (24) plus the size of the 255 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
252 * common action part (1) 256 memset(mgmt, 0, hdr_len);
253 */
254 mgmt = (struct ieee80211_mgmt *)
255 skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action));
256 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action));
257 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 257 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
258 IEEE80211_STYPE_ACTION); 258 IEEE80211_STYPE_ACTION);
259 259
@@ -867,9 +867,19 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
867 return; 867 return;
868 } 868 }
869 869
870 spin_lock_bh(&mpath->state_lock);
871 if (mpath->flags & MESH_PATH_REQ_QUEUED) {
872 spin_unlock_bh(&mpath->state_lock);
873 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
874 return;
875 }
876
870 memcpy(preq_node->dst, mpath->dst, ETH_ALEN); 877 memcpy(preq_node->dst, mpath->dst, ETH_ALEN);
871 preq_node->flags = flags; 878 preq_node->flags = flags;
872 879
880 mpath->flags |= MESH_PATH_REQ_QUEUED;
881 spin_unlock_bh(&mpath->state_lock);
882
873 list_add_tail(&preq_node->list, &ifmsh->preq_queue.list); 883 list_add_tail(&preq_node->list, &ifmsh->preq_queue.list);
874 ++ifmsh->preq_queue_len; 884 ++ifmsh->preq_queue_len;
875 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); 885 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
@@ -921,6 +931,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
921 goto enddiscovery; 931 goto enddiscovery;
922 932
923 spin_lock_bh(&mpath->state_lock); 933 spin_lock_bh(&mpath->state_lock);
934 mpath->flags &= ~MESH_PATH_REQ_QUEUED;
924 if (preq_node->flags & PREQ_Q_F_START) { 935 if (preq_node->flags & PREQ_Q_F_START) {
925 if (mpath->flags & MESH_PATH_RESOLVING) { 936 if (mpath->flags & MESH_PATH_RESOLVING) {
926 spin_unlock_bh(&mpath->state_lock); 937 spin_unlock_bh(&mpath->state_lock);
@@ -1028,11 +1039,11 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
1028 mesh_queue_preq(mpath, PREQ_Q_F_START); 1039 mesh_queue_preq(mpath, PREQ_Q_F_START);
1029 } 1040 }
1030 1041
1031 if (skb_queue_len(&mpath->frame_queue) >= 1042 if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN)
1032 MESH_FRAME_QUEUE_LEN)
1033 skb_to_free = skb_dequeue(&mpath->frame_queue); 1043 skb_to_free = skb_dequeue(&mpath->frame_queue);
1034 1044
1035 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1045 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1046 ieee80211_set_qos_hdr(sdata, skb);
1036 skb_queue_tail(&mpath->frame_queue, skb); 1047 skb_queue_tail(&mpath->frame_queue, skb);
1037 if (skb_to_free) 1048 if (skb_to_free)
1038 mesh_path_discard_frame(skb_to_free, sdata); 1049 mesh_path_discard_frame(skb_to_free, sdata);
@@ -1061,6 +1072,7 @@ void mesh_path_timer(unsigned long data)
1061 } else if (mpath->discovery_retries < max_preq_retries(sdata)) { 1072 } else if (mpath->discovery_retries < max_preq_retries(sdata)) {
1062 ++mpath->discovery_retries; 1073 ++mpath->discovery_retries;
1063 mpath->discovery_timeout *= 2; 1074 mpath->discovery_timeout *= 2;
1075 mpath->flags &= ~MESH_PATH_REQ_QUEUED;
1064 spin_unlock_bh(&mpath->state_lock); 1076 spin_unlock_bh(&mpath->state_lock);
1065 mesh_queue_preq(mpath, 0); 1077 mesh_queue_preq(mpath, 0);
1066 } else { 1078 } else {