Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b77863b authored by Johannes Berg's avatar Johannes Berg
Browse files

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent 679ef4ea
Loading
Loading
Loading
Loading
+14 −6
Original line number Original line Diff line number Diff line
@@ -2655,6 +2655,7 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
			       u16 status_code, struct sk_buff *skb)
			       u16 status_code, struct sk_buff *skb)
{
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_tdls_data *tf;
	struct ieee80211_tdls_data *tf;


	tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
	tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
@@ -2674,8 +2675,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
		tf->u.setup_req.capability =
		tf->u.setup_req.capability =
			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));


		ieee80211_add_srates_ie(sdata, skb, false);
		ieee80211_add_srates_ie(sdata, skb, false,
		ieee80211_add_ext_srates_ie(sdata, skb, false);
					local->oper_channel->band);
		ieee80211_add_ext_srates_ie(sdata, skb, false,
					    local->oper_channel->band);
		ieee80211_tdls_add_ext_capab(skb);
		ieee80211_tdls_add_ext_capab(skb);
		break;
		break;
	case WLAN_TDLS_SETUP_RESPONSE:
	case WLAN_TDLS_SETUP_RESPONSE:
@@ -2688,8 +2691,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
		tf->u.setup_resp.capability =
		tf->u.setup_resp.capability =
			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));


		ieee80211_add_srates_ie(sdata, skb, false);
		ieee80211_add_srates_ie(sdata, skb, false,
		ieee80211_add_ext_srates_ie(sdata, skb, false);
					local->oper_channel->band);
		ieee80211_add_ext_srates_ie(sdata, skb, false,
					    local->oper_channel->band);
		ieee80211_tdls_add_ext_capab(skb);
		ieee80211_tdls_add_ext_capab(skb);
		break;
		break;
	case WLAN_TDLS_SETUP_CONFIRM:
	case WLAN_TDLS_SETUP_CONFIRM:
@@ -2727,6 +2732,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
			   u16 status_code, struct sk_buff *skb)
			   u16 status_code, struct sk_buff *skb)
{
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_mgmt *mgmt;
	struct ieee80211_mgmt *mgmt;


	mgmt = (void *)skb_put(skb, 24);
	mgmt = (void *)skb_put(skb, 24);
@@ -2749,8 +2755,10 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
		mgmt->u.action.u.tdls_discover_resp.capability =
		mgmt->u.action.u.tdls_discover_resp.capability =
			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));


		ieee80211_add_srates_ie(sdata, skb, false);
		ieee80211_add_srates_ie(sdata, skb, false,
		ieee80211_add_ext_srates_ie(sdata, skb, false);
					local->oper_channel->band);
		ieee80211_add_ext_srates_ie(sdata, skb, false,
					    local->oper_channel->band);
		ieee80211_tdls_add_ext_capab(skb);
		ieee80211_tdls_add_ext_capab(skb);
		break;
		break;
	default:
	default:
+5 −2
Original line number Original line Diff line number Diff line
@@ -1459,6 +1459,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
			     u8 channel);
			     u8 channel);
struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
					  u8 *dst, u32 ratemask,
					  u8 *dst, u32 ratemask,
					  struct ieee80211_channel *chan,
					  const u8 *ssid, size_t ssid_len,
					  const u8 *ssid, size_t ssid_len,
					  const u8 *ie, size_t ie_len,
					  const u8 *ie, size_t ie_len,
					  bool directed);
					  bool directed);
@@ -1489,9 +1490,11 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
			       u32 cap);
			       u32 cap);
int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
			    struct sk_buff *skb, bool need_basic);
			    struct sk_buff *skb, bool need_basic,
			    enum ieee80211_band band);
int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
				struct sk_buff *skb, bool need_basic);
				struct sk_buff *skb, bool need_basic,
				enum ieee80211_band band);


/* channel management */
/* channel management */
enum ieee80211_chan_mode {
enum ieee80211_chan_mode {
+4 −2
Original line number Original line Diff line number Diff line
@@ -258,8 +258,10 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
			pos = skb_put(skb, 2);
			pos = skb_put(skb, 2);
			memcpy(pos + 2, &plid, 2);
			memcpy(pos + 2, &plid, 2);
		}
		}
		if (ieee80211_add_srates_ie(sdata, skb, true) ||
		if (ieee80211_add_srates_ie(sdata, skb, true,
		    ieee80211_add_ext_srates_ie(sdata, skb, true) ||
					    local->oper_channel->band) ||
		    ieee80211_add_ext_srates_ie(sdata, skb, true,
						local->oper_channel->band) ||
		    mesh_add_rsn_ie(skb, sdata) ||
		    mesh_add_rsn_ie(skb, sdata) ||
		    mesh_add_meshid_ie(skb, sdata) ||
		    mesh_add_meshid_ie(skb, sdata) ||
		    mesh_add_meshconf_ie(skb, sdata))
		    mesh_add_meshconf_ie(skb, sdata))
+3 −1
Original line number Original line Diff line number Diff line
@@ -1683,7 +1683,9 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
		ssid_len = ssid[1];
		ssid_len = ssid[1];


	skb = ieee80211_build_probe_req(sdata, cbss->bssid,
	skb = ieee80211_build_probe_req(sdata, cbss->bssid,
					(u32) -1, ssid + 2, ssid_len,
					(u32) -1,
					sdata->local->oper_channel,
					ssid + 2, ssid_len,
					NULL, 0, true);
					NULL, 0, true);


	return skb;
	return skb;
+3 −3
Original line number Original line Diff line number Diff line
@@ -2303,7 +2303,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
	struct ieee80211_if_ap *ap = NULL;
	struct ieee80211_if_ap *ap = NULL;
	struct beacon_data *beacon;
	struct beacon_data *beacon;
	struct ieee80211_supported_band *sband;
	struct ieee80211_supported_band *sband;
	enum ieee80211_band band = local->hw.conf.channel->band;
	enum ieee80211_band band = local->oper_channel->band;
	struct ieee80211_tx_rate_control txrc;
	struct ieee80211_tx_rate_control txrc;


	sband = local->hw.wiphy->bands[band];
	sband = local->hw.wiphy->bands[band];
@@ -2429,9 +2429,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
		*pos++ = WLAN_EID_SSID;
		*pos++ = WLAN_EID_SSID;
		*pos++ = 0x0;
		*pos++ = 0x0;


		if (ieee80211_add_srates_ie(sdata, skb, true) ||
		if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
		    mesh_add_ds_params_ie(skb, sdata) ||
		    mesh_add_ds_params_ie(skb, sdata) ||
		    ieee80211_add_ext_srates_ie(sdata, skb, true) ||
		    ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
		    mesh_add_rsn_ie(skb, sdata) ||
		    mesh_add_rsn_ie(skb, sdata) ||
		    mesh_add_ht_cap_ie(skb, sdata) ||
		    mesh_add_ht_cap_ie(skb, sdata) ||
		    mesh_add_ht_oper_ie(skb, sdata) ||
		    mesh_add_ht_oper_ie(skb, sdata) ||
Loading