Skip to contentSkip to conversation

mac80211: disassociate when direct probe timed out

PATCH Superseded Stanislaw Gruszka 2 participants 7 messages Nov 7, 2011 mac80211

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mac80211: disassociate when direct probe timed out

We disassociate only in cfg80211 and upper layers when direct probe timed out. Mac80211 is not aware about connection problem until ieee80211_sta_connection_lost() and operate in associate mode. If in this time window, upper layers decide to change channel we can observe warnings like below:

WARNING: at include/net/mac80211.h:3081 rate_control_send_low+0x8b/0x10f [mac80211]()
Call Trace:
 <IRQ>  [<ffffffff81054c2e>] warn_slowpath_common+0x83/0x9b
 [<ffffffff81054c60>] warn_slowpath_null+0x1a/0x1c
 [<ffffffffa025d5ff>] rate_control_send_low+0x8b/0x10f [mac80211]
 [<ffffffffa02ab306>] rs_get_rate+0x138/0x215 [iwlagn]
 [<ffffffffa025d993>] rate_control_get_rate+0x86/0x14c [mac80211]
 [<ffffffffa0265f18>] invoke_tx_handlers+0x829/0xe7d [mac80211]
 [<ffffffff8124bbf9>] ? swiotlb_unmap_page+0x9/0xb
 [<ffffffffa02bfc93>] ? pci_unmap_single+0x54/0x5b [iwlagn]
 [<ffffffffa02665d1>] ieee80211_tx+0x65/0x90 [mac80211]
 [<ffffffffa026675b>] ieee80211_xmit+0x15f/0x16e [mac80211]
 [<ffffffff813cfdd4>] ? __alloc_skb+0x8d/0x133
 [<ffffffffa02671cc>] ieee80211_tx_skb+0x56/0x5e [mac80211]
 [<ffffffffa02547ea>] ieee80211_send_bar+0xda/0xe9 [mac80211]
 [<ffffffffa024f5cf>] ieee80211_tx_status+0x1e1/0x706 [mac80211]
 [<ffffffff8148867c>] ? _raw_spin_unlock_irqrestore+0x17/0x19
 [<ffffffffa024eb5b>] ieee80211_tasklet_handler+0x5b/0xa8 [mac80211]

WARNING: at include/net/mac80211.h:3081 rate_control_send_low+0x8b/0x10f [mac80211]()
Call Trace:
 [<ffffffff81054c8e>] warn_slowpath_common+0x83/0x9b
 [<ffffffff81054cc0>] warn_slowpath_null+0x1a/0x1c
 [<ffffffffa0248627>] rate_control_send_low+0x8b/0x10f [mac80211]
 [<ffffffffa029d306>] rs_get_rate+0x138/0x215 [iwlagn]
 [<ffffffffa02489bb>] rate_control_get_rate+0x86/0x14c [mac80211]
 [<ffffffffa0250f2c>] invoke_tx_handlers+0x829/0xe7d [mac80211]
 [<ffffffffa02515e5>] ieee80211_tx+0x65/0x90 [mac80211]
 [<ffffffffa025176f>] ieee80211_xmit+0x15f/0x16e [mac80211]
 [<ffffffff813cf834>] ? __alloc_skb+0x8d/0x133
 [<ffffffffa02521e0>] ieee80211_tx_skb+0x56/0x5e [mac80211]
 [<ffffffffa023ef74>] ieee80211_send_delba+0x136/0x145 [mac80211]
 [<ffffffffa0240062>] ___ieee80211_stop_rx_ba_session+0xdc/0x10e [mac80211]
 [<ffffffffa02400e5>] __ieee80211_stop_rx_ba_session+0x51/0x68 [mac80211]
 [<ffffffffa023fc01>] ? ieee80211_start_tx_ba_cb+0x5b/0xd2 [mac80211]
 [<ffffffffa023ece5>] ieee80211_sta_tear_down_BA_sessions+0x50/0x5d [mac80211]
 [<ffffffffa0241be7>] ieee80211_set_disassoc+0xd1/0x1ee [mac80211]
 [<ffffffffa0241eb0>] ieee80211_sta_connection_lost+0x45/0x98 [mac80211]
 [<ffffffffa024450a>] ieee80211_sta_work+0x119/0x12c [mac80211]
 [<ffffffffa0247003>] ieee80211_iface_work+0x2af/0x2d2 [mac80211]

Lukasz, who can reproduce these warnings when switching between APs confirmed patch fixes the problem in his setup.

---
Ccing to 3.0+ stable only because warnings showed up after update to that kernel version. Even if problem existed before, it for some reason did not manifest itself.

 net/mac80211/mlme.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)
net/mac80211/mlme.c +9 -2
index 57fb58f..0946772 100644
@@ -2379,9 +2379,16 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
 			  struct sk_buff *skb)
 {
 	struct ieee80211_local *local = wk->sdata->local;
+	struct ieee80211_if_managed *ifmgd = &wk->sdata->u.mgd;
 
 	if (!skb) {
 		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
+
+		mutex_lock(&ifmgd->mtx);
+		if (ifmgd->associated)
+			ieee80211_set_disassoc(wk->sdata, true, false);
+		mutex_unlock(&ifmgd->mtx);
+
 		goto destroy;
 	}
 
@@ -2390,9 +2397,9 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
 		goto destroy;
 	}
 
-	mutex_lock(&wk->sdata->u.mgd.mtx);
+	mutex_lock(&ifmgd->mtx);
 	ieee80211_rx_mgmt_probe_resp(wk->sdata, skb);
-	mutex_unlock(&wk->sdata->u.mgd.mtx);
+	mutex_unlock(&ifmgd->mtx);
 
 	wk->type = IEEE80211_WORK_AUTH;
 	wk->probe_auth.tries = 0;
Signature · 1 line
1.7.1
#1 lore raw

net/mac80211/mlme.c ieee80211_probe_auth_done(struct ieee80211_work *wk, · line 2390

Quoted 7 lines · Stanislaw Gruszka
net/mac80211/mlme.c +5 -0
 	if (!skb) {
 		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
+
+		mutex_lock(&ifmgd->mtx);
+		if (ifmgd->associated)
+			ieee80211_set_disassoc(wk->sdata, true, false);
+		mutex_unlock(&ifmgd->mtx);

Patch tested by Lukasz was a bit different, it first did ieee80211_set_dissasoc() and then cfg80211_send_auth_timeout(). I changed order by accident when forward porting, I think it's better to apply the orginal order, I'll post v2.

Stanislaw

#2 lore raw

PATCH v2 1/1 mac80211: disassociate when direct probe timed out

We disassociate only in cfg80211 and upper layers when direct probe timed out. Mac80211 is not aware about connection problem until ieee80211_sta_connection_lost() and operate in associate mode. If in this time window, upper layers decide to change channel we can observe warnings like below:

WARNING: at include/net/mac80211.h:3081 rate_control_send_low+0x8b/0x10f [mac80211]()
Call Trace:
 <IRQ>  [<ffffffff81054c2e>] warn_slowpath_common+0x83/0x9b
 [<ffffffff81054c60>] warn_slowpath_null+0x1a/0x1c
 [<ffffffffa025d5ff>] rate_control_send_low+0x8b/0x10f [mac80211]
 [<ffffffffa02ab306>] rs_get_rate+0x138/0x215 [iwlagn]
 [<ffffffffa025d993>] rate_control_get_rate+0x86/0x14c [mac80211]
 [<ffffffffa0265f18>] invoke_tx_handlers+0x829/0xe7d [mac80211]
 [<ffffffff8124bbf9>] ? swiotlb_unmap_page+0x9/0xb
 [<ffffffffa02bfc93>] ? pci_unmap_single+0x54/0x5b [iwlagn]
 [<ffffffffa02665d1>] ieee80211_tx+0x65/0x90 [mac80211]
 [<ffffffffa026675b>] ieee80211_xmit+0x15f/0x16e [mac80211]
 [<ffffffff813cfdd4>] ? __alloc_skb+0x8d/0x133
 [<ffffffffa02671cc>] ieee80211_tx_skb+0x56/0x5e [mac80211]
 [<ffffffffa02547ea>] ieee80211_send_bar+0xda/0xe9 [mac80211]
 [<ffffffffa024f5cf>] ieee80211_tx_status+0x1e1/0x706 [mac80211]
 [<ffffffff8148867c>] ? _raw_spin_unlock_irqrestore+0x17/0x19
 [<ffffffffa024eb5b>] ieee80211_tasklet_handler+0x5b/0xa8 [mac80211]

WARNING: at include/net/mac80211.h:3081 rate_control_send_low+0x8b/0x10f [mac80211]()
Call Trace:
 [<ffffffff81054c8e>] warn_slowpath_common+0x83/0x9b
 [<ffffffff81054cc0>] warn_slowpath_null+0x1a/0x1c
 [<ffffffffa0248627>] rate_control_send_low+0x8b/0x10f [mac80211]
 [<ffffffffa029d306>] rs_get_rate+0x138/0x215 [iwlagn]
 [<ffffffffa02489bb>] rate_control_get_rate+0x86/0x14c [mac80211]
 [<ffffffffa0250f2c>] invoke_tx_handlers+0x829/0xe7d [mac80211]
 [<ffffffffa02515e5>] ieee80211_tx+0x65/0x90 [mac80211]
 [<ffffffffa025176f>] ieee80211_xmit+0x15f/0x16e [mac80211]
 [<ffffffff813cf834>] ? __alloc_skb+0x8d/0x133
 [<ffffffffa02521e0>] ieee80211_tx_skb+0x56/0x5e [mac80211]
 [<ffffffffa023ef74>] ieee80211_send_delba+0x136/0x145 [mac80211]
 [<ffffffffa0240062>] ___ieee80211_stop_rx_ba_session+0xdc/0x10e [mac80211]
 [<ffffffffa02400e5>] __ieee80211_stop_rx_ba_session+0x51/0x68 [mac80211]
 [<ffffffffa023fc01>] ? ieee80211_start_tx_ba_cb+0x5b/0xd2 [mac80211]
 [<ffffffffa023ece5>] ieee80211_sta_tear_down_BA_sessions+0x50/0x5d [mac80211]
 [<ffffffffa0241be7>] ieee80211_set_disassoc+0xd1/0x1ee [mac80211]
 [<ffffffffa0241eb0>] ieee80211_sta_connection_lost+0x45/0x98 [mac80211]
 [<ffffffffa024450a>] ieee80211_sta_work+0x119/0x12c [mac80211]
 [<ffffffffa0247003>] ieee80211_iface_work+0x2af/0x2d2 [mac80211]

Lukasz, who can reproduce these warnings when switching between APs confirmed patch fixes the problem in his setup.

---
Ccing to 3.0+ stable only because warnings showed up after update to that kernel version. Even if problem existed before, it for some reason did not manifest itself.

v1 -> v2 change order, first do mac80211 disassociate

 net/mac80211/mlme.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)
net/mac80211/mlme.c +8 -2
index 57fb58f..5147f38 100644
@@ -2379,8 +2379,14 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
 			  struct sk_buff *skb)
 {
 	struct ieee80211_local *local = wk->sdata->local;
+	struct ieee80211_if_managed *ifmgd = &wk->sdata->u.mgd;
 
 	if (!skb) {
+		mutex_lock(&ifmgd->mtx);
+		if (ifmgd->associated)
+			ieee80211_set_disassoc(wk->sdata, true, false);
+		mutex_unlock(&ifmgd->mtx);
+
 		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
 		goto destroy;
 	}
@@ -2390,9 +2396,9 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
 		goto destroy;
 	}
 
-	mutex_lock(&wk->sdata->u.mgd.mtx);
+	mutex_lock(&ifmgd->mtx);
 	ieee80211_rx_mgmt_probe_resp(wk->sdata, skb);
-	mutex_unlock(&wk->sdata->u.mgd.mtx);
+	mutex_unlock(&ifmgd->mtx);
 
 	wk->type = IEEE80211_WORK_AUTH;
 	wk->probe_auth.tries = 0;
Signature · 1 line
1.7.1
maintainer
#3 lore raw
Quoted 6 lines · Stanislaw Gruszka

+++ b/net/mac80211/mlme.c

net/mac80211/mlme.c +1 -0
@@ -2379,8 +2379,14 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
 			  struct sk_buff *skb)
 {
 	struct ieee80211_local *local = wk->sdata->local;
+	struct ieee80211_if_managed *ifmgd = &wk->sdata->u.mgd;

net/mac80211/mlme.c ieee80211_probe_auth_done(struct ieee80211_work *wk, · line 2392

Quoted 10 lines
net/mac80211/mlme.c +5 -0
 
 	if (!skb) {
+		mutex_lock(&ifmgd->mtx);
+		if (ifmgd->associated)
+			ieee80211_set_disassoc(wk->sdata, true, false);
+		mutex_unlock(&ifmgd->mtx);
+
 		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
 		goto destroy;
 	}

This doesn't seem right -- we can authenticate with a new AP while connected to an old one, but if the connection to the new one fails why should we tear down the connection to the *old* one?

johannes

maintainer
#4 lore raw
Quoted 9 lines · Johannes Berg
Quoted 7 lines · Stanislaw Gruszka

+++ b/net/mac80211/mlme.c

net/mac80211/mlme.c +1 -0
@@ -2379,8 +2379,14 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
 			  struct sk_buff *skb)
 {
 	struct ieee80211_local *local = wk->sdata->local;
+	struct ieee80211_if_managed *ifmgd = &wk->sdata->u.mgd;
 
Quoted 13 lines

net/mac80211/mlme.c ieee80211_probe_auth_done(struct ieee80211_work *wk, · line 2392

Quoted 9 lines
net/mac80211/mlme.c +5 -0
 	if (!skb) {
+		mutex_lock(&ifmgd->mtx);
+		if (ifmgd->associated)
+			ieee80211_set_disassoc(wk->sdata, true, false);
+		mutex_unlock(&ifmgd->mtx);
+
 		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
 		goto destroy;
 	}

This doesn't seem right -- we can authenticate with a new AP while connected to an old one, but if the connection to the new one fails why should we tear down the connection to the *old* one?

Also, we should never be able to get into a situation where the new AP is the same as the old AP as cfg80211 won't let you authenticate with a BSS that you're connected to (I believe).

johannes

#5 lore raw
Quoted 24 lines · Johannes Berg
Quoted 9 lines · Johannes Berg
Quoted 7 lines · Stanislaw Gruszka

+++ b/net/mac80211/mlme.c

net/mac80211/mlme.c +1 -0
@@ -2379,8 +2379,14 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
 			  struct sk_buff *skb)
 {
 	struct ieee80211_local *local = wk->sdata->local;
+	struct ieee80211_if_managed *ifmgd = &wk->sdata->u.mgd;
 
Quoted 13 lines

net/mac80211/mlme.c ieee80211_probe_auth_done(struct ieee80211_work *wk, · line 2392

Quoted 9 lines
net/mac80211/mlme.c +5 -0
 	if (!skb) {
+		mutex_lock(&ifmgd->mtx);
+		if (ifmgd->associated)
+			ieee80211_set_disassoc(wk->sdata, true, false);
+		mutex_unlock(&ifmgd->mtx);
+
 		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
 		goto destroy;
 	}

This doesn't seem right -- we can authenticate with a new AP while connected to an old one, but if the connection to the new one fails why should we tear down the connection to the *old* one?

Quoted 3 lines

Also, we should never be able to get into a situation where the new AP is the same as the old AP as cfg80211 won't let you authenticate with a BSS that you're connected to (I believe).

Oh, I see. So this problem happens with roaming, and we are doing something wrong with channels switching. Johannes, do you have idea how to possibly fix that? Here is full dmesg from Lukasz with warnings:
http://bugzilla.redhat.com/attachment.cgi?id=523540

Stanislaw

maintainer
#6 lore raw
Quoted 25 lines · Stanislaw Gruszka
Quoted 24 lines · Johannes Berg
Quoted 22 lines · Johannes Berg
Quoted 6 lines · Stanislaw Gruszka

+++ b/net/mac80211/mlme.c

net/mac80211/mlme.c +1 -0
@@ -2379,8 +2379,14 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
 			  struct sk_buff *skb)
 {
 	struct ieee80211_local *local = wk->sdata->local;
+	struct ieee80211_if_managed *ifmgd = &wk->sdata->u.mgd;

net/mac80211/mlme.c ieee80211_probe_auth_done(struct ieee80211_work *wk, · line 2392

Quoted 10 lines
net/mac80211/mlme.c +5 -0
 
 	if (!skb) {
+		mutex_lock(&ifmgd->mtx);
+		if (ifmgd->associated)
+			ieee80211_set_disassoc(wk->sdata, true, false);
+		mutex_unlock(&ifmgd->mtx);
+
 		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
 		goto destroy;
 	}

This doesn't seem right -- we can authenticate with a new AP while connected to an old one, but if the connection to the new one fails why should we tear down the connection to the *old* one?

Quoted 8 lines
Quoted 3 lines

Also, we should never be able to get into a situation where the new AP is the same as the old AP as cfg80211 won't let you authenticate with a BSS that you're connected to (I believe).

Oh, I see. So this problem happens with roaming, and we are doing something wrong with channels switching. Johannes, do you have idea how to possibly fix that? Here is full dmesg from Lukasz with warnings:
http://bugzilla.redhat.com/attachment.cgi?id=523540

I think I'll just have to set up this scenario in mac80211_hwsim. It must be related to the work.c channel stuff.

johannes