Message ID | m34l02mh71.fsf@t19.piap.pl (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Johannes Berg |
Headers | show |
Series | 802.11n IBSS: wlan0 stops receiving packets due to aggregation after sender reboot | expand |
I encountered the same issue in an IBSS-RSN network, where quick reboot of a station would cause issues with aggregation because the kernel is not aware of the reboot. I figured out that since wpa_supplicant already detect reboots, the simplest way to fix it would be for wpa_supplicant to reset the entire state of the station in the kernel, instead of just resetting keys and port. This means extending NL80211_CMD_DEL_STATION to work in IBSS mode too. My current wpa_supplicant patch tries this new API but fall back to the old methods if an error is returned. The changes required for drivers would be as follow: - mac80211: will just work - wil6210: does not seem to support IBSS mode - ath6kl: need a patch - brcmfmac: need a patch - mwifiex: need a patch - qtnfmac: no IBSS support - staging/wilc1000: no IBSS support - staging/rtl8723bs: already returns EINVAL in this case. I made patches for ath6kl, brcmfmac and mwifiex that plainly reject the request. If there is a better way, i'll glad to hear it.
Hi Nicolas, Nicolas Cavallari <nicolas.cavallari@green-communications.fr> writes: > I encountered the same issue in an IBSS-RSN network, where quick reboot > of a station would cause issues with aggregation because the kernel is > not aware of the reboot. > > I figured out that since wpa_supplicant already detect reboots, the > simplest way to fix it would be for wpa_supplicant to reset the entire > state of the station in the kernel, instead of just resetting keys and > port. Just to make sure everybody is aware that it would only be a partial fix - unencrypted ad hoc mode (the simplest thing available) doesn't need any userspace and thus must be fixed in the kernel. Alternatively this functionality may be moved to wpa_supplicant and only then userspace fix could really fix it completely.
Hi Krzysztof, On 11/12/2019 07:58, Krzysztof Hałasa wrote: > Hi Nicolas, > > Just to make sure everybody is aware that it would only be a partial fix > - unencrypted ad hoc mode (the simplest thing available) doesn't need > any userspace and thus must be fixed in the kernel. Alternatively this > functionality may be moved to wpa_supplicant and only then userspace fix > could really fix it completely. A partial fix is better than no fix. In any case, the IBSS-RSN and unencrypted IBSS cannot be fixed the same way. Having the kernel automatically reset a station while wpa_supplicant may have started a 4 way handshake with it had already lead to problems in the past. Which is why the kernel no longer reset stations (52874a5e). In any case, the unencrypted ibss case is probably much harder to fix, since even in a linux-only world, there are probably fullmac drivers for hardware that don't reply to open system auth in an open ibss. Anyway, this patch allows userspace to fix it, using whatever policy the user chooses to detect it.
--- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -354,9 +354,10 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, */ rcu_read_lock(); tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); - if (tid_rx && tid_rx->timeout == timeout) + if (tid_rx && tid_rx->timeout == timeout) { status = WLAN_STATUS_SUCCESS; - else + printk(KERN_DEBUG "AGG RX no change - OK: ssn %u\n", start_seq_num); + } else status = WLAN_STATUS_REQUEST_DECLINED; rcu_read_unlock(); goto end; @@ -434,6 +437,7 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, tid_agg_rx->tid = tid; tid_agg_rx->sta = sta; status = WLAN_STATUS_SUCCESS; + printk(KERN_DEBUG "AGG RX OK: ssn %u\n", start_seq_num); /* activate it for RX */ rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx); --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1298,9 +1298,11 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata /* frame with out of date sequence number */ if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) { + printk(KERN_DEBUG "SEQ BAD: %u vs %u\n", mpdu_seq_num, head_seq_num); dev_kfree_skb(skb); goto out; - } + } else + printk(KERN_DEBUG "SEQ OK: %u vs %u\n", mpdu_seq_num, head_seq_num); /* * If frame the sequence number exceeds our buffering window