mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
mac80211: dont add BSS when creating IBSS
There's no need to create a BSS struct only to pass it to ieee80211_sta_join_ibss, so refactor this function into __ieee80211_sta_join_ibss which takes all the relevant paramters, and ieee80211_sta_join_ibss which takes a BSS struct (used when joining an IBSS that already has other members). Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
2a51931192
commit
99cf5f5f35
3 changed files with 60 additions and 58 deletions
|
@ -953,9 +953,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
||||||
struct ieee80211_channel *channel,
|
struct ieee80211_channel *channel,
|
||||||
bool beacon);
|
bool beacon);
|
||||||
struct ieee80211_bss *
|
struct ieee80211_bss *
|
||||||
ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
|
|
||||||
u8 *ssid, u8 ssid_len);
|
|
||||||
struct ieee80211_bss *
|
|
||||||
ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
|
ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
|
||||||
u8 *ssid, u8 ssid_len);
|
u8 *ssid, u8 ssid_len);
|
||||||
void ieee80211_rx_bss_put(struct ieee80211_local *local,
|
void ieee80211_rx_bss_put(struct ieee80211_local *local,
|
||||||
|
|
|
@ -546,14 +546,15 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
|
||||||
|
|
||||||
/* MLME */
|
/* MLME */
|
||||||
static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
|
static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_bss *bss)
|
const size_t supp_rates_len,
|
||||||
|
const u8 *supp_rates)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
int i, have_higher_than_11mbit = 0;
|
int i, have_higher_than_11mbit = 0;
|
||||||
|
|
||||||
/* cf. IEEE 802.11 9.2.12 */
|
/* cf. IEEE 802.11 9.2.12 */
|
||||||
for (i = 0; i < bss->supp_rates_len; i++)
|
for (i = 0; i < supp_rates_len; i++)
|
||||||
if ((bss->supp_rates[i] & 0x7f) * 5 > 110)
|
if ((supp_rates[i] & 0x7f) * 5 > 110)
|
||||||
have_higher_than_11mbit = 1;
|
have_higher_than_11mbit = 1;
|
||||||
|
|
||||||
if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
|
if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
|
||||||
|
@ -1546,9 +1547,13 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_if_sta *ifsta,
|
struct ieee80211_if_sta *ifsta,
|
||||||
struct ieee80211_bss *bss)
|
const u8 *bssid, const int beacon_int,
|
||||||
|
const int freq,
|
||||||
|
const size_t supp_rates_len,
|
||||||
|
const u8 *supp_rates,
|
||||||
|
const u16 capability)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
int res = 0, rates, i, j;
|
int res = 0, rates, i, j;
|
||||||
|
@ -1564,7 +1569,7 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) &&
|
if ((ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) &&
|
||||||
memcmp(ifsta->bssid, bss->bssid, ETH_ALEN) == 0)
|
memcmp(ifsta->bssid, bssid, ETH_ALEN) == 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
|
skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
|
||||||
|
@ -1575,28 +1580,28 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
|
||||||
|
|
||||||
if (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) {
|
if (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) {
|
||||||
/* Remove possible STA entries from other IBSS networks. */
|
/* Remove possible STA entries from other IBSS networks. */
|
||||||
sta_info_flush_delayed(sdata);
|
sta_info_flush_delayed(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
|
memcpy(ifsta->bssid, bssid, ETH_ALEN);
|
||||||
res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
|
res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;
|
local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
|
||||||
|
|
||||||
sdata->drop_unencrypted = bss->capability &
|
sdata->drop_unencrypted = capability &
|
||||||
WLAN_CAPABILITY_PRIVACY ? 1 : 0;
|
WLAN_CAPABILITY_PRIVACY ? 1 : 0;
|
||||||
|
|
||||||
res = ieee80211_set_freq(sdata, bss->freq);
|
res = ieee80211_set_freq(sdata, freq);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
||||||
|
|
||||||
/* Build IBSS probe response */
|
/* Build IBSS probe response */
|
||||||
|
|
||||||
skb_reserve(skb, local->hw.extra_tx_headroom);
|
skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||||
|
@ -1611,27 +1616,26 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
|
memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
|
||||||
mgmt->u.beacon.beacon_int =
|
mgmt->u.beacon.beacon_int =
|
||||||
cpu_to_le16(local->hw.conf.beacon_int);
|
cpu_to_le16(local->hw.conf.beacon_int);
|
||||||
mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp);
|
mgmt->u.beacon.capab_info = cpu_to_le16(capability);
|
||||||
mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);
|
|
||||||
|
|
||||||
pos = skb_put(skb, 2 + ifsta->ssid_len);
|
pos = skb_put(skb, 2 + ifsta->ssid_len);
|
||||||
*pos++ = WLAN_EID_SSID;
|
*pos++ = WLAN_EID_SSID;
|
||||||
*pos++ = ifsta->ssid_len;
|
*pos++ = ifsta->ssid_len;
|
||||||
memcpy(pos, ifsta->ssid, ifsta->ssid_len);
|
memcpy(pos, ifsta->ssid, ifsta->ssid_len);
|
||||||
|
|
||||||
rates = bss->supp_rates_len;
|
rates = supp_rates_len;
|
||||||
if (rates > 8)
|
if (rates > 8)
|
||||||
rates = 8;
|
rates = 8;
|
||||||
pos = skb_put(skb, 2 + rates);
|
pos = skb_put(skb, 2 + rates);
|
||||||
*pos++ = WLAN_EID_SUPP_RATES;
|
*pos++ = WLAN_EID_SUPP_RATES;
|
||||||
*pos++ = rates;
|
*pos++ = rates;
|
||||||
memcpy(pos, bss->supp_rates, rates);
|
memcpy(pos, supp_rates, rates);
|
||||||
|
|
||||||
if (bss->band == IEEE80211_BAND_2GHZ) {
|
if (sband->band == IEEE80211_BAND_2GHZ) {
|
||||||
pos = skb_put(skb, 2 + 1);
|
pos = skb_put(skb, 2 + 1);
|
||||||
*pos++ = WLAN_EID_DS_PARAMS;
|
*pos++ = WLAN_EID_DS_PARAMS;
|
||||||
*pos++ = 1;
|
*pos++ = 1;
|
||||||
*pos++ = ieee80211_frequency_to_channel(bss->freq);
|
*pos++ = ieee80211_frequency_to_channel(freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = skb_put(skb, 2 + 2);
|
pos = skb_put(skb, 2 + 2);
|
||||||
|
@ -1641,12 +1645,12 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
*pos++ = 0;
|
*pos++ = 0;
|
||||||
*pos++ = 0;
|
*pos++ = 0;
|
||||||
|
|
||||||
if (bss->supp_rates_len > 8) {
|
if (supp_rates_len > 8) {
|
||||||
rates = bss->supp_rates_len - 8;
|
rates = supp_rates_len - 8;
|
||||||
pos = skb_put(skb, 2 + rates);
|
pos = skb_put(skb, 2 + rates);
|
||||||
*pos++ = WLAN_EID_EXT_SUPP_RATES;
|
*pos++ = WLAN_EID_EXT_SUPP_RATES;
|
||||||
*pos++ = rates;
|
*pos++ = rates;
|
||||||
memcpy(pos, &bss->supp_rates[8], rates);
|
memcpy(pos, &supp_rates[8], rates);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_extra_ies(skb, sdata->u.sta.ie_proberesp,
|
add_extra_ies(skb, sdata->u.sta.ie_proberesp,
|
||||||
|
@ -1659,16 +1663,15 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
||||||
|
|
||||||
rates = 0;
|
rates = 0;
|
||||||
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
for (i = 0; i < supp_rates_len; i++) {
|
||||||
for (i = 0; i < bss->supp_rates_len; i++) {
|
int bitrate = (supp_rates[i] & 0x7f) * 5;
|
||||||
int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
|
|
||||||
for (j = 0; j < sband->n_bitrates; j++)
|
for (j = 0; j < sband->n_bitrates; j++)
|
||||||
if (sband->bitrates[j].bitrate == bitrate)
|
if (sband->bitrates[j].bitrate == bitrate)
|
||||||
rates |= BIT(j);
|
rates |= BIT(j);
|
||||||
}
|
}
|
||||||
ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
|
ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
|
||||||
|
|
||||||
ieee80211_sta_def_wmm_params(sdata, bss);
|
ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
|
||||||
|
|
||||||
ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
|
ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
|
||||||
ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
|
ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
|
||||||
|
@ -1677,12 +1680,23 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
ieee80211_led_assoc(local, true);
|
ieee80211_led_assoc(local, true);
|
||||||
|
|
||||||
memset(&wrqu, 0, sizeof(wrqu));
|
memset(&wrqu, 0, sizeof(wrqu));
|
||||||
memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
|
memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
|
||||||
wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
|
wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct ieee80211_if_sta *ifsta,
|
||||||
|
struct ieee80211_bss *bss)
|
||||||
|
{
|
||||||
|
return __ieee80211_sta_join_ibss(sdata, ifsta,
|
||||||
|
bss->bssid, bss->beacon_int,
|
||||||
|
bss->freq,
|
||||||
|
bss->supp_rates_len, bss->supp_rates,
|
||||||
|
bss->capability);
|
||||||
|
}
|
||||||
|
|
||||||
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_mgmt *mgmt,
|
struct ieee80211_mgmt *mgmt,
|
||||||
size_t len,
|
size_t len,
|
||||||
|
@ -2251,11 +2265,12 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_if_sta *ifsta)
|
struct ieee80211_if_sta *ifsta)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
struct ieee80211_bss *bss;
|
|
||||||
struct ieee80211_supported_band *sband;
|
struct ieee80211_supported_band *sband;
|
||||||
u8 bssid[ETH_ALEN], *pos;
|
u8 *pos;
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
|
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
|
||||||
|
u16 capability;
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET) {
|
if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET) {
|
||||||
memcpy(bssid, ifsta->bssid, ETH_ALEN);
|
memcpy(bssid, ifsta->bssid, ETH_ALEN);
|
||||||
|
@ -2273,36 +2288,29 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
|
||||||
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
|
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
|
||||||
sdata->dev->name, bssid);
|
sdata->dev->name, bssid);
|
||||||
|
|
||||||
bss = ieee80211_rx_bss_add(local, bssid,
|
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
||||||
local->hw.conf.channel->center_freq,
|
|
||||||
sdata->u.sta.ssid, sdata->u.sta.ssid_len);
|
|
||||||
if (!bss)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
bss->band = local->hw.conf.channel->band;
|
|
||||||
sband = local->hw.wiphy->bands[bss->band];
|
|
||||||
|
|
||||||
if (local->hw.conf.beacon_int == 0)
|
if (local->hw.conf.beacon_int == 0)
|
||||||
local->hw.conf.beacon_int = 100;
|
local->hw.conf.beacon_int = 100;
|
||||||
bss->beacon_int = local->hw.conf.beacon_int;
|
|
||||||
bss->last_update = jiffies;
|
capability = WLAN_CAPABILITY_IBSS;
|
||||||
bss->capability = WLAN_CAPABILITY_IBSS;
|
|
||||||
|
|
||||||
if (sdata->default_key)
|
if (sdata->default_key)
|
||||||
bss->capability |= WLAN_CAPABILITY_PRIVACY;
|
capability |= WLAN_CAPABILITY_PRIVACY;
|
||||||
else
|
else
|
||||||
sdata->drop_unencrypted = 0;
|
sdata->drop_unencrypted = 0;
|
||||||
|
|
||||||
bss->supp_rates_len = sband->n_bitrates;
|
pos = supp_rates;
|
||||||
pos = bss->supp_rates;
|
|
||||||
for (i = 0; i < sband->n_bitrates; i++) {
|
for (i = 0; i < sband->n_bitrates; i++) {
|
||||||
int rate = sband->bitrates[i].bitrate;
|
int rate = sband->bitrates[i].bitrate;
|
||||||
*pos++ = (u8) (rate / 5);
|
*pos++ = (u8) (rate / 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
|
return __ieee80211_sta_join_ibss(sdata, ifsta,
|
||||||
ieee80211_rx_bss_put(local, bss);
|
bssid, local->hw.conf.beacon_int,
|
||||||
return ret;
|
local->hw.conf.channel->center_freq,
|
||||||
|
sband->n_bitrates, supp_rates,
|
||||||
|
capability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2471,7 +2479,8 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
|
||||||
ieee80211_sta_set_ssid(sdata, selected->ssid,
|
ieee80211_sta_set_ssid(sdata, selected->ssid,
|
||||||
selected->ssid_len);
|
selected->ssid_len);
|
||||||
ieee80211_sta_set_bssid(sdata, selected->bssid);
|
ieee80211_sta_set_bssid(sdata, selected->bssid);
|
||||||
ieee80211_sta_def_wmm_params(sdata, selected);
|
ieee80211_sta_def_wmm_params(sdata, selected->supp_rates_len,
|
||||||
|
selected->supp_rates);
|
||||||
if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED)
|
if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED)
|
||||||
sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED;
|
sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED;
|
||||||
else
|
else
|
||||||
|
|
|
@ -14,11 +14,7 @@
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* figure out how to avoid that the "current BSS" expires
|
* figure out how to avoid that the "current BSS" expires
|
||||||
* clean up IBSS code (in MLME), see why it adds a BSS to the list
|
* use cfg80211's BSS handling
|
||||||
* use cfg80211's BSS handling (depends on IBSS TODO above)
|
|
||||||
* order BSS list by RSSI(?) ("quality of AP")
|
|
||||||
* scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
|
|
||||||
* SSID)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/wireless.h>
|
#include <linux/wireless.h>
|
||||||
|
@ -107,7 +103,7 @@ static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ieee80211_bss *
|
static struct ieee80211_bss *
|
||||||
ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
|
ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
|
||||||
u8 *ssid, u8 ssid_len)
|
u8 *ssid, u8 ssid_len)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue