Commit 86a1b9d7 authored by Markus Theil's avatar Markus Theil Committed by Johannes Berg

mac80211: fix control port tx status check

The initial control port tx status patch assumed, that
we have IEEE 802.11 frames, but actually ethernet frames
are stored in the ack skb. Fix this by checking for the
correct ethertype and skb protocol 802.3.

Also allow tx status reports for ETH_P_PREAUTH, as preauth
frames can also be send over the nl80211 control port.

Fixes: a7528198 ("mac80211: support control port TX status reporting")
Reported-by: default avatarJouni Malinen <j@w1.fi>
Signed-off-by: default avatarMarkus Theil <markus.theil@tu-ilmenau.de>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/r/20200622123542.173695-1-markus.theil@tu-ilmenau.deSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 0c1a7f13
...@@ -639,11 +639,23 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local, ...@@ -639,11 +639,23 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,
u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie; u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie;
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_hdr *hdr = (void *)skb->data;
__be16 ethertype = 0;
if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3))
skb_copy_bits(skb, 2 * ETH_ALEN, &ethertype, ETH_TLEN);
rcu_read_lock(); rcu_read_lock();
sdata = ieee80211_sdata_from_skb(local, skb); sdata = ieee80211_sdata_from_skb(local, skb);
if (sdata) { if (sdata) {
if (ieee80211_is_any_nullfunc(hdr->frame_control)) if (ethertype == sdata->control_port_protocol ||
ethertype == cpu_to_be16(ETH_P_PREAUTH))
cfg80211_control_port_tx_status(&sdata->wdev,
cookie,
skb->data,
skb->len,
acked,
GFP_ATOMIC);
else if (ieee80211_is_any_nullfunc(hdr->frame_control))
cfg80211_probe_status(sdata->dev, hdr->addr1, cfg80211_probe_status(sdata->dev, hdr->addr1,
cookie, acked, cookie, acked,
info->status.ack_signal, info->status.ack_signal,
...@@ -654,12 +666,8 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local, ...@@ -654,12 +666,8 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,
skb->data, skb->len, skb->data, skb->len,
acked, GFP_ATOMIC); acked, GFP_ATOMIC);
else else
cfg80211_control_port_tx_status(&sdata->wdev, pr_warn("Unknown status report in ack skb\n");
cookie,
skb->data,
skb->len,
acked,
GFP_ATOMIC);
} }
rcu_read_unlock(); rcu_read_unlock();
......
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