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

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

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
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ mac80211-y := \
	scan.o offchannel.o \
	ht.o agg-tx.o agg-rx.o \
	ibss.o \
	mlme.o work.o \
	work.o \
	iface.o \
	rate.o \
	michael.o \
@@ -25,7 +25,7 @@ mac80211-y := \
	wme.o \
	event.o \
	chan.o \
	driver-trace.o
	driver-trace.o mlme.o

mac80211-$(CONFIG_MAC80211_LEDS) += led.o
mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
+3 −3
Original line number Diff line number Diff line
@@ -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)
		cfg80211_mgmt_tx_status(wk->sdata->dev,
					(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;
}
@@ -2179,8 +2179,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
	wk->done = ieee80211_offchan_tx_done;
	wk->offchan_tx.frame = skb;
	wk->offchan_tx.wait = wait;
	wk->ie_len = len;
	memcpy(wk->ie, buf, len);
	wk->data_len = len;
	memcpy(wk->data, buf, len);

	ieee80211_add_work(wk);
	return 0;
+41 −36
Original line number Diff line number Diff line
@@ -280,10 +280,6 @@ struct mesh_preq_queue {

enum ieee80211_work_type {
	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_OFFCHANNEL_TX,
};
@@ -316,35 +312,9 @@ struct ieee80211_work {
	unsigned long timeout;
	enum ieee80211_work_type type;

	u8 filter_ta[ETH_ALEN];

	bool started;

	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 {
			u32 duration;
		} remain;
@@ -355,9 +325,8 @@ struct ieee80211_work {
		} offchan_tx;
	};

	int ie_len;
	/* must be last */
	u8 ie[0];
	size_t data_len;
	u8 data[];
};

/* flags used in struct ieee80211_if_managed.flags */
@@ -373,6 +342,43 @@ enum ieee80211_sta_flags {
	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 timer_list timer;
	struct timer_list conn_mon_timer;
@@ -389,6 +395,8 @@ struct ieee80211_if_managed {

	struct mutex mtx;
	struct cfg80211_bss *associated;
	struct ieee80211_mgd_auth_data *auth_data;
	struct ieee80211_mgd_assoc_data *assoc_data;

	u8 bssid[ETH_ALEN];

@@ -770,7 +778,6 @@ struct ieee80211_local {
	struct list_head work_list;
	struct timer_list work_timer;
	struct work_struct work_work;
	struct sk_buff_head work_skb_queue;

	/*
	 * private workqueue to mac80211. mac80211 makes this accessible
@@ -1437,8 +1444,6 @@ void ieee80211_work_init(struct ieee80211_local *local);
void ieee80211_add_work(struct ieee80211_work *wk);
void free_work(struct ieee80211_work *wk);
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,
				   struct ieee80211_channel *chan,
				   enum nl80211_channel_type channel_type,
+3 −1
Original line number Diff line number Diff line
@@ -1310,7 +1310,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)

		/* do not count disabled managed interfaces */
		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;
			continue;
		}
+1 −9
Original line number Diff line number Diff line
@@ -199,15 +199,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
		return;

	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
		/*
		 * 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)
		sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
	else if (sdata->vif.type == NL80211_IFTYPE_AP)
Loading