Commit 6b77863b719a4e32909c218c0d5a83a14f4d98c5

Authored by Johannes Berg
1 parent 679ef4eadd

mac80211: fix current vs. operating channel in preq/beacon

When sending probe requests, e.g. during software scanning,
these will go out on the *current* channel, so their IEs
need to be built from the current channel. At other times,
e.g. for beacons or probe request templates, the IEs will
be used on the *operating* channel and using the current
channel instead might result in errors.

Add the appropriate parameters to respect the difference.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>

Showing 6 changed files with 44 additions and 26 deletions Side-by-side Diff

... ... @@ -2655,6 +2655,7 @@
2655 2655 u16 status_code, struct sk_buff *skb)
2656 2656 {
2657 2657 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  2658 + struct ieee80211_local *local = sdata->local;
2658 2659 struct ieee80211_tdls_data *tf;
2659 2660  
2660 2661 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
... ... @@ -2674,8 +2675,10 @@
2674 2675 tf->u.setup_req.capability =
2675 2676 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2676 2677  
2677   - ieee80211_add_srates_ie(sdata, skb, false);
2678   - ieee80211_add_ext_srates_ie(sdata, skb, false);
  2678 + ieee80211_add_srates_ie(sdata, skb, false,
  2679 + local->oper_channel->band);
  2680 + ieee80211_add_ext_srates_ie(sdata, skb, false,
  2681 + local->oper_channel->band);
2679 2682 ieee80211_tdls_add_ext_capab(skb);
2680 2683 break;
2681 2684 case WLAN_TDLS_SETUP_RESPONSE:
... ... @@ -2688,8 +2691,10 @@
2688 2691 tf->u.setup_resp.capability =
2689 2692 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2690 2693  
2691   - ieee80211_add_srates_ie(sdata, skb, false);
2692   - ieee80211_add_ext_srates_ie(sdata, skb, false);
  2694 + ieee80211_add_srates_ie(sdata, skb, false,
  2695 + local->oper_channel->band);
  2696 + ieee80211_add_ext_srates_ie(sdata, skb, false,
  2697 + local->oper_channel->band);
2693 2698 ieee80211_tdls_add_ext_capab(skb);
2694 2699 break;
2695 2700 case WLAN_TDLS_SETUP_CONFIRM:
... ... @@ -2727,6 +2732,7 @@
2727 2732 u16 status_code, struct sk_buff *skb)
2728 2733 {
2729 2734 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  2735 + struct ieee80211_local *local = sdata->local;
2730 2736 struct ieee80211_mgmt *mgmt;
2731 2737  
2732 2738 mgmt = (void *)skb_put(skb, 24);
... ... @@ -2749,8 +2755,10 @@
2749 2755 mgmt->u.action.u.tdls_discover_resp.capability =
2750 2756 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2751 2757  
2752   - ieee80211_add_srates_ie(sdata, skb, false);
2753   - ieee80211_add_ext_srates_ie(sdata, skb, false);
  2758 + ieee80211_add_srates_ie(sdata, skb, false,
  2759 + local->oper_channel->band);
  2760 + ieee80211_add_ext_srates_ie(sdata, skb, false,
  2761 + local->oper_channel->band);
2754 2762 ieee80211_tdls_add_ext_capab(skb);
2755 2763 break;
2756 2764 default:
net/mac80211/ieee80211_i.h
... ... @@ -1459,6 +1459,7 @@
1459 1459 u8 channel);
1460 1460 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1461 1461 u8 *dst, u32 ratemask,
  1462 + struct ieee80211_channel *chan,
1462 1463 const u8 *ssid, size_t ssid_len,
1463 1464 const u8 *ie, size_t ie_len,
1464 1465 bool directed);
1465 1466  
... ... @@ -1489,9 +1490,11 @@
1489 1490 u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1490 1491 u32 cap);
1491 1492 int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1492   - struct sk_buff *skb, bool need_basic);
  1493 + struct sk_buff *skb, bool need_basic,
  1494 + enum ieee80211_band band);
1493 1495 int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1494   - struct sk_buff *skb, bool need_basic);
  1496 + struct sk_buff *skb, bool need_basic,
  1497 + enum ieee80211_band band);
1495 1498  
1496 1499 /* channel management */
1497 1500 enum ieee80211_chan_mode {
net/mac80211/mesh_plink.c
... ... @@ -258,8 +258,10 @@
258 258 pos = skb_put(skb, 2);
259 259 memcpy(pos + 2, &plid, 2);
260 260 }
261   - if (ieee80211_add_srates_ie(sdata, skb, true) ||
262   - ieee80211_add_ext_srates_ie(sdata, skb, true) ||
  261 + if (ieee80211_add_srates_ie(sdata, skb, true,
  262 + local->oper_channel->band) ||
  263 + ieee80211_add_ext_srates_ie(sdata, skb, true,
  264 + local->oper_channel->band) ||
263 265 mesh_add_rsn_ie(skb, sdata) ||
264 266 mesh_add_meshid_ie(skb, sdata) ||
265 267 mesh_add_meshconf_ie(skb, sdata))
... ... @@ -1683,7 +1683,9 @@
1683 1683 ssid_len = ssid[1];
1684 1684  
1685 1685 skb = ieee80211_build_probe_req(sdata, cbss->bssid,
1686   - (u32) -1, ssid + 2, ssid_len,
  1686 + (u32) -1,
  1687 + sdata->local->oper_channel,
  1688 + ssid + 2, ssid_len,
1687 1689 NULL, 0, true);
1688 1690  
1689 1691 return skb;
... ... @@ -2303,7 +2303,7 @@
2303 2303 struct ieee80211_if_ap *ap = NULL;
2304 2304 struct beacon_data *beacon;
2305 2305 struct ieee80211_supported_band *sband;
2306   - enum ieee80211_band band = local->hw.conf.channel->band;
  2306 + enum ieee80211_band band = local->oper_channel->band;
2307 2307 struct ieee80211_tx_rate_control txrc;
2308 2308  
2309 2309 sband = local->hw.wiphy->bands[band];
2310 2310  
... ... @@ -2429,9 +2429,9 @@
2429 2429 *pos++ = WLAN_EID_SSID;
2430 2430 *pos++ = 0x0;
2431 2431  
2432   - if (ieee80211_add_srates_ie(sdata, skb, true) ||
  2432 + if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
2433 2433 mesh_add_ds_params_ie(skb, sdata) ||
2434   - ieee80211_add_ext_srates_ie(sdata, skb, true) ||
  2434 + ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
2435 2435 mesh_add_rsn_ie(skb, sdata) ||
2436 2436 mesh_add_ht_cap_ie(skb, sdata) ||
2437 2437 mesh_add_ht_oper_ie(skb, sdata) ||
... ... @@ -1100,6 +1100,7 @@
1100 1100  
1101 1101 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1102 1102 u8 *dst, u32 ratemask,
  1103 + struct ieee80211_channel *chan,
1103 1104 const u8 *ssid, size_t ssid_len,
1104 1105 const u8 *ie, size_t ie_len,
1105 1106 bool directed)
... ... @@ -1109,7 +1110,7 @@
1109 1110 struct ieee80211_mgmt *mgmt;
1110 1111 size_t buf_len;
1111 1112 u8 *buf;
1112   - u8 chan;
  1113 + u8 chan_no;
1113 1114  
1114 1115 /* FIXME: come up with a proper value */
1115 1116 buf = kmalloc(200 + ie_len, GFP_KERNEL);
1116 1117  
1117 1118  
... ... @@ -1122,14 +1123,12 @@
1122 1123 * badly-behaved APs don't respond when this parameter is included.
1123 1124 */
1124 1125 if (directed)
1125   - chan = 0;
  1126 + chan_no = 0;
1126 1127 else
1127   - chan = ieee80211_frequency_to_channel(
1128   - local->hw.conf.channel->center_freq);
  1128 + chan_no = ieee80211_frequency_to_channel(chan->center_freq);
1129 1129  
1130   - buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
1131   - local->hw.conf.channel->band,
1132   - ratemask, chan);
  1130 + buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, chan->band,
  1131 + ratemask, chan_no);
1133 1132  
1134 1133 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1135 1134 ssid, ssid_len,
... ... @@ -1158,7 +1157,9 @@
1158 1157 {
1159 1158 struct sk_buff *skb;
1160 1159  
1161   - skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len,
  1160 + skb = ieee80211_build_probe_req(sdata, dst, ratemask,
  1161 + sdata->local->hw.conf.channel,
  1162 + ssid, ssid_len,
1162 1163 ie, ie_len, directed);
1163 1164 if (skb) {
1164 1165 if (no_cck)
... ... @@ -1810,7 +1811,8 @@
1810 1811 }
1811 1812  
1812 1813 int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1813   - struct sk_buff *skb, bool need_basic)
  1814 + struct sk_buff *skb, bool need_basic,
  1815 + enum ieee80211_band band)
1814 1816 {
1815 1817 struct ieee80211_local *local = sdata->local;
1816 1818 struct ieee80211_supported_band *sband;
... ... @@ -1818,7 +1820,7 @@
1818 1820 u8 i, rates, *pos;
1819 1821 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
1820 1822  
1821   - sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
  1823 + sband = local->hw.wiphy->bands[band];
1822 1824 rates = sband->n_bitrates;
1823 1825 if (rates > 8)
1824 1826 rates = 8;
... ... @@ -1841,7 +1843,8 @@
1841 1843 }
1842 1844  
1843 1845 int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1844   - struct sk_buff *skb, bool need_basic)
  1846 + struct sk_buff *skb, bool need_basic,
  1847 + enum ieee80211_band band)
1845 1848 {
1846 1849 struct ieee80211_local *local = sdata->local;
1847 1850 struct ieee80211_supported_band *sband;
... ... @@ -1849,7 +1852,7 @@
1849 1852 u8 i, exrates, *pos;
1850 1853 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
1851 1854  
1852   - sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
  1855 + sband = local->hw.wiphy->bands[band];
1853 1856 exrates = sband->n_bitrates;
1854 1857 if (exrates > 8)
1855 1858 exrates -= 8;