Skip to content

Commit

Permalink
mac80211: preserve more bits when building QoS header
Browse files Browse the repository at this point in the history
Michael Braun reported that when trying to inject A-MSDUs over
monitor interfaces, the frame doesn't come out right since the
QoS header A-MSDU bit is overwritten.

Rather than adding that bit specifically simply preserve those
bits that we don't set here, since we typically get here with
a zeroed-out QoS header anyway.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Johannes Berg committed Oct 12, 2016
1 parent 72f15d5 commit 32910bb
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions net/mac80211/wme.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,26 +236,35 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_hdr *hdr = (void *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
u8 flags;
u8 *p;
u8 ack_policy, tid;

if (!ieee80211_is_data_qos(hdr->frame_control))
return;

p = ieee80211_get_qos_ctl(hdr);
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;

/* preserve EOSP bit */
ack_policy = *p & IEEE80211_QOS_CTL_EOSP;
/* set up the first byte */

/*
* preserve everything but the TID and ACK policy
* (which we both write here)
*/
flags = *p & ~(IEEE80211_QOS_CTL_TID_MASK |
IEEE80211_QOS_CTL_ACK_POLICY_MASK);

if (is_multicast_ether_addr(hdr->addr1) ||
sdata->noack_map & BIT(tid)) {
ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
flags |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
info->flags |= IEEE80211_TX_CTL_NO_ACK;
}

/* qos header is 2 bytes */
*p++ = ack_policy | tid;
*p = flags | tid;

/* set up the second byte */
p++;

if (ieee80211_vif_is_mesh(&sdata->vif)) {
/* preserve RSPI and Mesh PS Level bit */
*p &= ((IEEE80211_QOS_CTL_RSPI |
Expand Down

0 comments on commit 32910bb

Please sign in to comment.