Commit 99cf5f5f authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2a519311
...@@ -953,9 +953,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
...@@ -1605,33 +1610,32 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -1605,33 +1610,32 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
skb_put(skb, 24 + sizeof(mgmt->u.beacon)); skb_put(skb, 24 + sizeof(mgmt->u.beacon));
memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_PROBE_RESP); IEEE80211_STYPE_PROBE_RESP);
memset(mgmt->da, 0xff, ETH_ALEN); memset(mgmt->da, 0xff, ETH_ALEN);
memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment