aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Oh <peter.oh@bowerswilkins.com>2018-01-26 17:02:37 -0500
committerJohannes Berg <johannes.berg@intel.com>2018-01-31 06:39:10 -0500
commitc4de37ee2b55deac7d6aeac33e02e3d6be243898 (patch)
tree60d27e43a9eb5de6039cf37fc5983ffc3c095338
parentc028c6309a9f9b385ba8c0c984eb2b6c3f368650 (diff)
mac80211: mesh: fix wrong mesh TTL offset calculation
mesh TTL offset in Mesh Channel Switch Parameters element depends on not only Secondary Channel Offset element, but also affected by HT Control field and Wide Bandwidth Channel Switch element. So use element structure to manipulate mesh channel swich param IE after removing its constant attribution to correct the miscalculation. Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/mesh.c17
2 files changed, 7 insertions, 12 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 885d00b41911..61db1fb156ed 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1467,7 +1467,7 @@ struct ieee802_11_elems {
1467 const struct ieee80211_timeout_interval_ie *timeout_int; 1467 const struct ieee80211_timeout_interval_ie *timeout_int;
1468 const u8 *opmode_notif; 1468 const u8 *opmode_notif;
1469 const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; 1469 const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
1470 const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie; 1470 struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie;
1471 const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie; 1471 const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie;
1472 1472
1473 /* length of them, respectively */ 1473 /* length of them, respectively */
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 5e27364e10ac..23555536bad5 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1253,13 +1253,12 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
1253} 1253}
1254 1254
1255static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, 1255static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
1256 struct ieee80211_mgmt *mgmt, size_t len) 1256 struct ieee80211_mgmt *mgmt, size_t len,
1257 struct ieee802_11_elems *elems)
1257{ 1258{
1258 struct ieee80211_mgmt *mgmt_fwd; 1259 struct ieee80211_mgmt *mgmt_fwd;
1259 struct sk_buff *skb; 1260 struct sk_buff *skb;
1260 struct ieee80211_local *local = sdata->local; 1261 struct ieee80211_local *local = sdata->local;
1261 u8 *pos = mgmt->u.action.u.chan_switch.variable;
1262 size_t offset_ttl;
1263 1262
1264 skb = dev_alloc_skb(local->tx_headroom + len); 1263 skb = dev_alloc_skb(local->tx_headroom + len);
1265 if (!skb) 1264 if (!skb)
@@ -1267,13 +1266,9 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
1267 skb_reserve(skb, local->tx_headroom); 1266 skb_reserve(skb, local->tx_headroom);
1268 mgmt_fwd = skb_put(skb, len); 1267 mgmt_fwd = skb_put(skb, len);
1269 1268
1270 /* offset_ttl is based on whether the secondary channel 1269 elems->mesh_chansw_params_ie->mesh_ttl--;
1271 * offset is available or not. Subtract 1 from the mesh TTL 1270 elems->mesh_chansw_params_ie->mesh_flags &=
1272 * and disable the initiator flag before forwarding. 1271 ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
1273 */
1274 offset_ttl = (len < 42) ? 7 : 10;
1275 *(pos + offset_ttl) -= 1;
1276 *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
1277 1272
1278 memcpy(mgmt_fwd, mgmt, len); 1273 memcpy(mgmt_fwd, mgmt, len);
1279 eth_broadcast_addr(mgmt_fwd->da); 1274 eth_broadcast_addr(mgmt_fwd->da);
@@ -1321,7 +1316,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
1321 1316
1322 /* forward or re-broadcast the CSA frame */ 1317 /* forward or re-broadcast the CSA frame */
1323 if (fwd_csa) { 1318 if (fwd_csa) {
1324 if (mesh_fwd_csa_frame(sdata, mgmt, len) < 0) 1319 if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0)
1325 mcsa_dbg(sdata, "Failed to forward the CSA frame"); 1320 mcsa_dbg(sdata, "Failed to forward the CSA frame");
1326 } 1321 }
1327} 1322}