Commit 66e67e41 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: redesign auth/assoc

This is the second part of the auth/assoc redesign,
the mac80211 part. This moves the auth/assoc code
out of the work abstraction and into the MLME, so
that we don't flip channels all the time etc.

The only downside is that when we are associated,
we need to drop the association in order to create
a connection to another AP, but for most drivers
this is actually desirable and the ability to do
was never used by any applications. If we want to
implement resource reservation with FT-OTA, we'd
probably best do it with explicit R-O-C in wpa_s.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 4c0c0b75
...@@ -9,7 +9,7 @@ mac80211-y := \ ...@@ -9,7 +9,7 @@ mac80211-y := \
scan.o offchannel.o \ scan.o offchannel.o \
ht.o agg-tx.o agg-rx.o \ ht.o agg-tx.o agg-rx.o \
ibss.o \ ibss.o \
mlme.o work.o \ work.o \
iface.o \ iface.o \
rate.o \ rate.o \
michael.o \ michael.o \
...@@ -25,7 +25,7 @@ mac80211-y := \ ...@@ -25,7 +25,7 @@ mac80211-y := \
wme.o \ wme.o \
event.o \ event.o \
chan.o \ chan.o \
driver-trace.o driver-trace.o mlme.o
mac80211-$(CONFIG_MAC80211_LEDS) += led.o mac80211-$(CONFIG_MAC80211_LEDS) += led.o
mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
......
...@@ -2028,7 +2028,7 @@ ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb) ...@@ -2028,7 +2028,7 @@ ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb)
if (wk->offchan_tx.wait && !wk->offchan_tx.status) if (wk->offchan_tx.wait && !wk->offchan_tx.status)
cfg80211_mgmt_tx_status(wk->sdata->dev, cfg80211_mgmt_tx_status(wk->sdata->dev,
(unsigned long) wk->offchan_tx.frame, (unsigned long) wk->offchan_tx.frame,
wk->ie, wk->ie_len, false, GFP_KERNEL); wk->data, wk->data_len, false, GFP_KERNEL);
return WORK_DONE_DESTROY; return WORK_DONE_DESTROY;
} }
...@@ -2179,8 +2179,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, ...@@ -2179,8 +2179,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
wk->done = ieee80211_offchan_tx_done; wk->done = ieee80211_offchan_tx_done;
wk->offchan_tx.frame = skb; wk->offchan_tx.frame = skb;
wk->offchan_tx.wait = wait; wk->offchan_tx.wait = wait;
wk->ie_len = len; wk->data_len = len;
memcpy(wk->ie, buf, len); memcpy(wk->data, buf, len);
ieee80211_add_work(wk); ieee80211_add_work(wk);
return 0; return 0;
......
...@@ -280,10 +280,6 @@ struct mesh_preq_queue { ...@@ -280,10 +280,6 @@ struct mesh_preq_queue {
enum ieee80211_work_type { enum ieee80211_work_type {
IEEE80211_WORK_ABORT, IEEE80211_WORK_ABORT,
IEEE80211_WORK_DIRECT_PROBE,
IEEE80211_WORK_AUTH,
IEEE80211_WORK_ASSOC_BEACON_WAIT,
IEEE80211_WORK_ASSOC,
IEEE80211_WORK_REMAIN_ON_CHANNEL, IEEE80211_WORK_REMAIN_ON_CHANNEL,
IEEE80211_WORK_OFFCHANNEL_TX, IEEE80211_WORK_OFFCHANNEL_TX,
}; };
...@@ -316,35 +312,9 @@ struct ieee80211_work { ...@@ -316,35 +312,9 @@ struct ieee80211_work {
unsigned long timeout; unsigned long timeout;
enum ieee80211_work_type type; enum ieee80211_work_type type;
u8 filter_ta[ETH_ALEN];
bool started; bool started;
union { union {
struct {
int tries;
u16 algorithm, transaction;
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len;
u8 key[WLAN_KEY_LEN_WEP104];
u8 key_len, key_idx;
bool privacy;
bool synced;
} probe_auth;
struct {
struct cfg80211_bss *bss;
const u8 *supp_rates;
const u8 *ht_information_ie;
enum ieee80211_smps_mode smps;
int tries;
u16 capability;
u8 prev_bssid[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len;
u8 supp_rates_len;
bool wmm_used, use_11n, uapsd_used;
bool synced;
} assoc;
struct { struct {
u32 duration; u32 duration;
} remain; } remain;
...@@ -355,9 +325,8 @@ struct ieee80211_work { ...@@ -355,9 +325,8 @@ struct ieee80211_work {
} offchan_tx; } offchan_tx;
}; };
int ie_len; size_t data_len;
/* must be last */ u8 data[];
u8 ie[0];
}; };
/* flags used in struct ieee80211_if_managed.flags */ /* flags used in struct ieee80211_if_managed.flags */
...@@ -373,6 +342,43 @@ enum ieee80211_sta_flags { ...@@ -373,6 +342,43 @@ enum ieee80211_sta_flags {
IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9), IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
}; };
struct ieee80211_mgd_auth_data {
struct cfg80211_bss *bss;
unsigned long timeout;
int tries;
u16 algorithm, expected_transaction;
u8 key[WLAN_KEY_LEN_WEP104];
u8 key_len, key_idx;
bool synced;
bool done;
size_t ie_len;
u8 ie[];
};
struct ieee80211_mgd_assoc_data {
struct cfg80211_bss *bss;
const u8 *supp_rates;
const u8 *ht_information_ie;
unsigned long timeout;
int tries;
u16 capability;
u8 prev_bssid[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len;
u8 supp_rates_len;
bool wmm_used, uapsd_used;
bool have_beacon;
bool sent_assoc;
bool synced;
size_t ie_len;
u8 ie[];
};
struct ieee80211_if_managed { struct ieee80211_if_managed {
struct timer_list timer; struct timer_list timer;
struct timer_list conn_mon_timer; struct timer_list conn_mon_timer;
...@@ -389,6 +395,8 @@ struct ieee80211_if_managed { ...@@ -389,6 +395,8 @@ struct ieee80211_if_managed {
struct mutex mtx; struct mutex mtx;
struct cfg80211_bss *associated; struct cfg80211_bss *associated;
struct ieee80211_mgd_auth_data *auth_data;
struct ieee80211_mgd_assoc_data *assoc_data;
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
...@@ -770,7 +778,6 @@ struct ieee80211_local { ...@@ -770,7 +778,6 @@ struct ieee80211_local {
struct list_head work_list; struct list_head work_list;
struct timer_list work_timer; struct timer_list work_timer;
struct work_struct work_work; struct work_struct work_work;
struct sk_buff_head work_skb_queue;
/* /*
* private workqueue to mac80211. mac80211 makes this accessible * private workqueue to mac80211. mac80211 makes this accessible
...@@ -1437,8 +1444,6 @@ void ieee80211_work_init(struct ieee80211_local *local); ...@@ -1437,8 +1444,6 @@ void ieee80211_work_init(struct ieee80211_local *local);
void ieee80211_add_work(struct ieee80211_work *wk); void ieee80211_add_work(struct ieee80211_work *wk);
void free_work(struct ieee80211_work *wk); void free_work(struct ieee80211_work *wk);
void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata); void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata);
ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata, int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type, enum nl80211_channel_type channel_type,
......
...@@ -1310,7 +1310,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) ...@@ -1310,7 +1310,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
/* do not count disabled managed interfaces */ /* do not count disabled managed interfaces */
if (sdata->vif.type == NL80211_IFTYPE_STATION && if (sdata->vif.type == NL80211_IFTYPE_STATION &&
!sdata->u.mgd.associated) { !sdata->u.mgd.associated &&
!sdata->u.mgd.auth_data &&
!sdata->u.mgd.assoc_data) {
sdata->vif.bss_conf.idle = true; sdata->vif.bss_conf.idle = true;
continue; continue;
} }
......
...@@ -199,15 +199,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, ...@@ -199,15 +199,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
return; return;
if (sdata->vif.type == NL80211_IFTYPE_STATION) { if (sdata->vif.type == NL80211_IFTYPE_STATION) {
/* sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
* While not associated, claim a BSSID of all-zeroes
* so that drivers don't do any weird things with the
* BSSID at that time.
*/
if (sdata->vif.bss_conf.assoc)
sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
else
sdata->vif.bss_conf.bssid = zero;
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
else if (sdata->vif.type == NL80211_IFTYPE_AP) else if (sdata->vif.type == NL80211_IFTYPE_AP)
......
This diff is collapsed.
...@@ -2484,14 +2484,9 @@ static ieee80211_rx_result debug_noinline ...@@ -2484,14 +2484,9 @@ static ieee80211_rx_result debug_noinline
ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
{ {
struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_sub_if_data *sdata = rx->sdata;
ieee80211_rx_result rxs;
struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
__le16 stype; __le16 stype;
rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);
if (rxs != RX_CONTINUE)
return rxs;
stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE); stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
if (!ieee80211_vif_is_mesh(&sdata->vif) && if (!ieee80211_vif_is_mesh(&sdata->vif) &&
...@@ -2500,10 +2495,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) ...@@ -2500,10 +2495,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
return RX_DROP_MONITOR; return RX_DROP_MONITOR;
switch (stype) { switch (stype) {
case cpu_to_le16(IEEE80211_STYPE_AUTH):
case cpu_to_le16(IEEE80211_STYPE_BEACON): case cpu_to_le16(IEEE80211_STYPE_BEACON):
case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
/* process for all: mesh, mlme, ibss */ /* process for all: mesh, mlme, ibss */
break; break;
case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
case cpu_to_le16(IEEE80211_STYPE_DEAUTH): case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
case cpu_to_le16(IEEE80211_STYPE_DISASSOC): case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
if (is_multicast_ether_addr(mgmt->da) && if (is_multicast_ether_addr(mgmt->da) &&
...@@ -2515,7 +2513,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) ...@@ -2515,7 +2513,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
return RX_DROP_MONITOR; return RX_DROP_MONITOR;
break; break;
case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ): case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
case cpu_to_le16(IEEE80211_STYPE_AUTH):
/* process only for ibss */ /* process only for ibss */
if (sdata->vif.type != NL80211_IFTYPE_ADHOC) if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
return RX_DROP_MONITOR; return RX_DROP_MONITOR;
......
This diff is collapsed.
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