/* * monitor mode reception * * This function cleans up the SKB, i.e. it removes all the stuff * only useful for monitoring.
*/ staticstruct sk_buff *ieee80211_clean_skb(struct sk_buff *skb, unsignedint present_fcs_len, unsignedint rtap_space)
{ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr; unsignedint hdrlen;
__le16 fc;
if (present_fcs_len)
__pskb_trim(skb, skb->len - present_fcs_len);
pskb_pull(skb, rtap_space);
/* After pulling radiotap header, clear all flags that indicate * info in skb->data.
*/
status->flag &= ~(RX_FLAG_RADIOTAP_TLV_AT_END |
RX_FLAG_RADIOTAP_LSIG |
RX_FLAG_RADIOTAP_HE_MU |
RX_FLAG_RADIOTAP_HE);
hdr = (void *)skb->data;
fc = hdr->frame_control;
/* * Remove the HT-Control field (if present) on management * frames after we've sent the frame to monitoring. We * (currently) don't need it, and don't properly parse * frames with it present, due to the assumption of a * fixed management header length.
*/ if (likely(!ieee80211_is_mgmt(fc) || !ieee80211_has_order(fc))) return skb;
/* allocate extra bitmaps */ if (status->chains)
len += 4 * hweight8(status->chains);
if (ieee80211_have_rx_timestamp(status)) {
len = ALIGN(len, 8);
len += 8;
} if (ieee80211_hw_check(&local->hw, SIGNAL_DBM))
len += 1;
/* antenna field, if we don't have per-chain info */ if (!status->chains)
len += 1;
/* padding for RX_FLAGS if necessary */
len = ALIGN(len, 2);
if (status->encoding == RX_ENC_HT) /* HT info */
len += 3;
if (status->flag & RX_FLAG_AMPDU_DETAILS) {
len = ALIGN(len, 4);
len += 8;
}
if (status->encoding == RX_ENC_VHT) {
len = ALIGN(len, 2);
len += 12;
}
if (local->hw.radiotap_timestamp.units_pos >= 0) {
len = ALIGN(len, 8);
len += 12;
}
if (status->encoding == RX_ENC_HE &&
status->flag & RX_FLAG_RADIOTAP_HE) {
len = ALIGN(len, 2);
len += 12;
BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) != 12);
}
if (status->encoding == RX_ENC_HE &&
status->flag & RX_FLAG_RADIOTAP_HE_MU) {
len = ALIGN(len, 2);
len += 12;
BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) != 12);
}
if (status->flag & RX_FLAG_NO_PSDU)
len += 1;
if (status->flag & RX_FLAG_RADIOTAP_LSIG) {
len = ALIGN(len, 2);
len += 4;
BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_lsig) != 4);
}
if (status->chains) { /* antenna and antenna signal fields */
len += 2 * hweight8(status->chains);
}
if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) { int tlv_offset = 0;
/* * The position to look at depends on the existence (or non- * existence) of other elements, so take that into account...
*/ if (status->flag & RX_FLAG_RADIOTAP_HE)
tlv_offset += sizeof(struct ieee80211_radiotap_he); if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
tlv_offset += sizeof(struct ieee80211_radiotap_he_mu); if (status->flag & RX_FLAG_RADIOTAP_LSIG)
tlv_offset += sizeof(struct ieee80211_radiotap_lsig);
/* ensure 4 byte alignment for TLV */
len = ALIGN(len, 4);
/* TLVs until the mac header */
len += skb_mac_header(skb) - &skb->data[tlv_offset];
}
if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) { /* data is pointer at tlv all other info was pulled off */
tlvs_len = skb_mac_header(skb) - skb->data;
}
if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END)
it_present_val |= BIT(IEEE80211_RADIOTAP_TLV);
put_unaligned_le32(it_present_val, it_present);
/* This references through an offset into it_optional[] rather * than via it_present otherwise later uses of pos will cause * the compiler to think we have walked past the end of the * struct member.
*/
pos = (void *)&rthdr->it_optional[it_present + 1 - rthdr->it_optional];
/* the order of the following fields is important */
/* IEEE80211_RADIOTAP_FLAGS */ if (has_fcs && ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS))
*pos |= IEEE80211_RADIOTAP_F_FCS; if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
*pos |= IEEE80211_RADIOTAP_F_BADFCS; if (status->enc_flags & RX_ENC_FLAG_SHORTPRE)
*pos |= IEEE80211_RADIOTAP_F_SHORTPRE;
pos++;
/* IEEE80211_RADIOTAP_RATE */ if (!rate || status->encoding != RX_ENC_LEGACY) { /* * Without rate information don't add it. If we have, * MCS information is a separate field in radiotap, * added below. The byte here is needed as padding * for the channel though, so initialise it to 0.
*/
*pos = 0;
} else { int shift = 0;
rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_RATE)); if (status->bw == RATE_INFO_BW_10)
shift = 1; elseif (status->bw == RATE_INFO_BW_5)
shift = 2;
*pos = DIV_ROUND_UP(rate->bitrate, 5 * (1 << shift));
}
pos++;
/* IEEE80211_RADIOTAP_CHANNEL */ /* TODO: frequency offset in KHz */
put_unaligned_le16(status->freq, pos);
pos += 2; if (status->bw == RATE_INFO_BW_10)
channel_flags |= IEEE80211_CHAN_HALF; elseif (status->bw == RATE_INFO_BW_5)
channel_flags |= IEEE80211_CHAN_QUARTER;
/* room for the radiotap header based on driver features */
rt_hdrlen = ieee80211_rx_radiotap_hdrlen(local, status, *origskb);
needed_headroom = rt_hdrlen - rtap_space;
if (use_origskb) { /* only need to expand headroom if necessary */
skb = *origskb;
*origskb = NULL;
/* * This shouldn't trigger often because most devices have an * RX header they pull before we get here, and that should * be big enough for our radiotap information. We should * probably export the length to drivers so that we can have * them allocate enough headroom to start with.
*/ if (skb_headroom(skb) < needed_headroom &&
pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) {
dev_kfree_skb(skb); return NULL;
}
} else { /* * Need to make a copy and possibly remove radiotap header * and FCS from the original.
*/
skb = skb_copy_expand(*origskb, needed_headroom + NET_SKB_PAD,
0, GFP_ATOMIC);
if (!skb) return NULL;
}
/* prepend radiotap information */
ieee80211_add_rx_radiotap_header(local, skb, rate, rt_hdrlen, true);
/* * This function copies a received frame to all monitor interfaces and * returns a cleaned-up SKB that no longer includes the FCS nor the * radiotap header the driver might have added.
*/ staticstruct sk_buff *
ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, struct ieee80211_rate *rate)
{ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); struct ieee80211_sub_if_data *sdata, *prev_sdata = NULL; struct sk_buff *skb, *monskb = NULL; int present_fcs_len = 0; unsignedint rtap_space = 0; struct ieee80211_sub_if_data *monitor_sdata =
rcu_dereference(local->monitor_sdata); bool only_monitor = false; unsignedint min_head_len;
if (WARN_ON_ONCE(status->flag & RX_FLAG_RADIOTAP_TLV_AT_END &&
!skb_mac_header_was_set(origskb))) { /* with this skb no way to know where frame payload starts */
dev_kfree_skb(origskb); return NULL;
}
if (status->flag & RX_FLAG_RADIOTAP_HE)
rtap_space += sizeof(struct ieee80211_radiotap_he);
if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
rtap_space += sizeof(struct ieee80211_radiotap_he_mu);
if (status->flag & RX_FLAG_RADIOTAP_LSIG)
rtap_space += sizeof(struct ieee80211_radiotap_lsig);
if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END)
rtap_space += skb_mac_header(origskb) - &origskb->data[rtap_space];
min_head_len = rtap_space;
/* * First, we may need to make a copy of the skb because * (1) we need to modify it for radiotap (if not present), and * (2) the other RX handlers will modify the skb we got. * * We don't need to, of course, if we aren't going to return * the SKB because it has a bad FCS/PLCP checksum.
*/
if (!(status->flag & RX_FLAG_NO_PSDU)) { if (ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)) { if (unlikely(origskb->len <= FCS_LEN + rtap_space)) { /* driver bug */
WARN_ON(1);
dev_kfree_skb(origskb); return NULL;
}
present_fcs_len = FCS_LEN;
}
/* also consider the hdr->frame_control */
min_head_len += 2;
}
/* ensure that the expected data elements are in skb head */ if (!pskb_may_pull(origskb, min_head_len)) {
dev_kfree_skb(origskb); return NULL;
}
/* does the frame have a qos control field? */ if (ieee80211_is_data_qos(hdr->frame_control)) {
u8 *qc = ieee80211_get_qos_ctl(hdr); /* frame has qos control */
tid = *qc & IEEE80211_QOS_CTL_TID_MASK; if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT)
status->rx_flags |= IEEE80211_RX_AMSDU;
seqno_idx = tid;
security_idx = tid;
} else { /* * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): * * Sequence numbers for management frames, QoS data * frames with a broadcast/multicast address in the * Address 1 field, and all non-QoS data frames sent * by QoS STAs are assigned using an additional single * modulo-4096 counter, [...] * * We also use that counter for non-QoS STAs.
*/
seqno_idx = IEEE80211_NUM_TIDS;
security_idx = 0; if (ieee80211_is_mgmt(hdr->frame_control))
security_idx = IEEE80211_NUM_TIDS;
tid = 0;
}
rx->seqno_idx = seqno_idx;
rx->security_idx = security_idx; /* Set skb->priority to 1d tag if highest order bit of TID is not set.
* For now, set skb->priority to 0 for other cases. */
rx->skb->priority = (tid > 7) ? 0 : tid;
}
/** * DOC: Packet alignment * * Drivers always need to pass packets that are aligned to two-byte boundaries * to the stack. * * Additionally, they should, if possible, align the payload data in a way that * guarantees that the contained IP header is aligned to a four-byte * boundary. In the case of regular frames, this simply means aligning the * payload to a four-byte boundary (because either the IP header is directly * contained, or IV/RFC1042 headers that have a length divisible by four are * in front of it). If the payload data is not properly aligned and the * architecture doesn't support efficient unaligned operations, mac80211 * will align the data. * * With A-MSDU frames, however, the payload data address must yield two modulo * four because there are 14-byte 802.3 headers within the A-MSDU frames that * push the IP header further back to a multiple of four again. Thankfully, the * specs were sane enough this time around to require padding each A-MSDU * subframe to a length that is a multiple of four. * * Padding like Atheros hardware adds which is between the 802.11 header and * the payload is not supported; the driver is required to move the 802.11 * header to be directly in front of the payload in that case.
*/ staticvoid ieee80211_verify_alignment(struct ieee80211_rx_data *rx)
{ #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
WARN_ON_ONCE((unsignedlong)rx->skb->data & 1); #endif
}
if (!is_multicast_ether_addr(hdr->addr1)) return 0;
return ieee80211_is_robust_mgmt_frame(skb);
}
/* Get the BIP key index from MMIE; return -1 if this is not a BIP frame */ staticint ieee80211_get_mmie_keyidx(struct sk_buff *skb)
{ struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data; struct ieee80211_mmie *mmie; struct ieee80211_mmie_16 *mmie16;
if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da)) return -1;
if (!ieee80211_is_robust_mgmt_frame(skb) &&
!ieee80211_is_beacon(hdr->frame_control)) return -1; /* not a robust management frame */
if (!ieee80211_rx_reorder_ready(tid_agg_rx, index)) {
__skb_queue_purge(skb_list); goto no_frame;
}
/* release frames from the reorder ring buffer */
tid_agg_rx->stored_mpdu_num--; while ((skb = __skb_dequeue(skb_list))) {
status = IEEE80211_SKB_RXCB(skb);
status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE;
__skb_queue_tail(frames, skb);
}
no_frame: if (tid_agg_rx->reorder_buf_filtered)
tid_agg_rx->reorder_buf_filtered &= ~BIT_ULL(index);
tid_agg_rx->head_seq_num = ieee80211_sn_inc(tid_agg_rx->head_seq_num);
}
while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) {
index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
frames);
}
}
/* * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If * the skb was added to the buffer longer than this time ago, the earlier * frames that have not yet been received are assumed to be lost and the skb * can be released for processing. This may also release other skb's from the * reorder buffer if there are no additional gaps between the frames. * * Callers must hold tid_agg_rx->reorder_lock.
*/ #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
staticvoid ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, struct sk_buff_head *frames)
{ int index, i, j;
lockdep_assert_held(&tid_agg_rx->reorder_lock);
/* release the buffer until next missing frame */
index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; if (!ieee80211_rx_reorder_ready(tid_agg_rx, index) &&
tid_agg_rx->stored_mpdu_num) { /* * No buffers ready to be released, but check whether any * frames in the reorder buffer have timed out.
*/ int skipped = 1; for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
j = (j + 1) % tid_agg_rx->buf_size) { if (!ieee80211_rx_reorder_ready(tid_agg_rx, j)) {
skipped++; continue;
} if (skipped &&
!time_after(jiffies, tid_agg_rx->reorder_time[j] +
HT_RX_REORDER_BUF_TIMEOUT)) goto set_release_timer;
/* don't leave incomplete A-MSDUs around */ for (i = (index + 1) % tid_agg_rx->buf_size; i != j;
i = (i + 1) % tid_agg_rx->buf_size)
__skb_queue_purge(&tid_agg_rx->reorder_buf[i]);
ht_dbg_ratelimited(sdata, "release an RX reorder frame due to timeout on earlier frames\n");
ieee80211_release_reorder_frame(sdata, tid_agg_rx, j,
frames);
/* * Increment the head seq# also for the skipped slots.
*/
tid_agg_rx->head_seq_num =
(tid_agg_rx->head_seq_num +
skipped) & IEEE80211_SN_MASK;
skipped = 0;
}
} elsewhile (ieee80211_rx_reorder_ready(tid_agg_rx, index)) {
ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
frames);
index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
}
if (tid_agg_rx->stored_mpdu_num) {
j = index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
/* * As this function belongs to the RX path it must be under * rcu_read_lock protection. It returns false if the frame * can be processed immediately, true if it was consumed.
*/ staticbool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, struct sk_buff *skb, struct sk_buff_head *frames)
{ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
u16 mpdu_seq_num = ieee80211_get_sn(hdr);
u16 head_seq_num, buf_size; int index; bool ret = true;
spin_lock(&tid_agg_rx->reorder_lock);
/* * Offloaded BA sessions have no known starting sequence number so pick * one from first Rxed frame for this tid after BA was started.
*/ if (unlikely(tid_agg_rx->auto_seq)) {
tid_agg_rx->auto_seq = false;
tid_agg_rx->ssn = mpdu_seq_num;
tid_agg_rx->head_seq_num = mpdu_seq_num;
}
/* * If the current MPDU's SN is smaller than the SSN, it shouldn't * be reordered.
*/ if (unlikely(!tid_agg_rx->started)) { if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
ret = false; goto out;
}
tid_agg_rx->started = true;
}
/* frame with out of date sequence number */ if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
dev_kfree_skb(skb); goto out;
}
/* * If frame the sequence number exceeds our buffering window * size release some previous frames to make room for this one.
*/ if (!ieee80211_sn_less(mpdu_seq_num, head_seq_num + buf_size)) {
head_seq_num = ieee80211_sn_inc(
ieee80211_sn_sub(mpdu_seq_num, buf_size)); /* release stored frames up to new head to stack */
ieee80211_release_reorder_frames(sdata, tid_agg_rx,
head_seq_num, frames);
}
/* Now the new frame is always in the range of the reordering buffer */
index = mpdu_seq_num % tid_agg_rx->buf_size;
/* check if we already stored this frame */ if (ieee80211_rx_reorder_ready(tid_agg_rx, index)) {
dev_kfree_skb(skb); goto out;
}
/* * If the current MPDU is in the right order and nothing else * is stored we can process it directly, no need to buffer it. * If it is first but there's something stored, we may be able * to release frames after this one.
*/ if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
tid_agg_rx->stored_mpdu_num == 0) { if (!(status->flag & RX_FLAG_AMSDU_MORE))
tid_agg_rx->head_seq_num =
ieee80211_sn_inc(tid_agg_rx->head_seq_num);
ret = false; goto out;
}
/* put the frame in the reordering buffer */
__skb_queue_tail(&tid_agg_rx->reorder_buf[index], skb); if (!(status->flag & RX_FLAG_AMSDU_MORE)) {
tid_agg_rx->reorder_time[index] = jiffies;
tid_agg_rx->stored_mpdu_num++;
ieee80211_sta_reorder_release(sdata, tid_agg_rx, frames);
}
/* qos null data frames are excluded */ if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) goto dont_reorder;
/* not part of a BA session */ if (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_NOACK) goto dont_reorder;
/* new, potentially un-ordered, ampdu frame - process it */
/* reset session timer */ if (tid_agg_rx->timeout)
tid_agg_rx->last_rx = jiffies;
/* if this mpdu is fragmented - terminate rx aggregation session */
sc = le16_to_cpu(hdr->seq_ctrl); if (sc & IEEE80211_SCTL_FRAG) {
ieee80211_queue_skb_to_iface(rx->sdata, rx->link_id, NULL, skb); return;
}
/* * No locking needed -- we will only ever process one * RX packet at a time, and thus own tid_agg_rx. All * other code manipulating it needs to (and does) make * sure that we cannot get to it any more before doing * anything with it.
*/ if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb,
frames)) return;
/* Drop disallowed frame classes based on STA auth/assoc state; * IEEE 802.11, Chap 5.5. * * mac80211 filters only based on association state, i.e. it drops * Class 3 frames from not associated stations. hostapd sends * deauth/disassoc frames when needed. In addition, hostapd is * responsible for filtering on both auth and assoc states.
*/
if (ieee80211_vif_is_mesh(&rx->sdata->vif)) return ieee80211_rx_mesh_check(rx);
if (unlikely((ieee80211_is_data(hdr->frame_control) ||
ieee80211_is_pspoll(hdr->frame_control)) &&
rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
rx->sdata->vif.type != NL80211_IFTYPE_OCB &&
(!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { /* * accept port control frames from the AP even when it's not * yet marked ASSOC to prevent a race where we don't set the * assoc bit quickly enough before it sends the first frame
*/ if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
ieee80211_is_data_present(hdr->frame_control)) { unsignedint hdrlen;
__be16 ethertype;
atomic_inc(&ps->num_sta_ps);
set_sta_flag(sta, WLAN_STA_PS_STA); if (!ieee80211_hw_check(&local->hw, AP_LINK_PS))
drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta);
ps_dbg(sdata, "STA %pM aid %d enters power save mode\n",
sta->sta.addr, sta->sta.aid);
ieee80211_clear_fast_xmit(sta);
for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { struct ieee80211_txq *txq = sta->sta.txq[tid]; struct txq_info *txqi = to_txq_info(txq);
spin_lock(&local->active_txq_lock[txq->ac]); if (!list_empty(&txqi->schedule_order))
list_del_init(&txqi->schedule_order);
spin_unlock(&local->active_txq_lock[txq->ac]);
if (txq_has_queue(txq))
set_bit(tid, &sta->txq_buffered_tids); else
clear_bit(tid, &sta->txq_buffered_tids);
}
}
staticvoid sta_ps_end(struct sta_info *sta)
{
ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n",
sta->sta.addr, sta->sta.aid);
if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { /* * Clear the flag only if the other one is still set * so that the TX path won't start TX'ing new frames * directly ... In the case that the driver flag isn't * set ieee80211_sta_ps_deliver_wakeup() will clear it.
*/
clear_sta_flag(sta, WLAN_STA_PS_STA);
ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n",
sta->sta.addr, sta->sta.aid); return;
}
/* Don't let the same PS state be set twice */
in_ps = test_sta_flag(sta, WLAN_STA_PS_STA); if ((start && in_ps) || (!start && !in_ps)) return -EINVAL;
if (start)
sta_ps_start(sta); else
sta_ps_end(sta);
if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
ieee80211_sta_ps_deliver_poll_response(sta); else
set_sta_flag(sta, WLAN_STA_PSPOLL);
}
EXPORT_SYMBOL(ieee80211_sta_pspoll);
void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid)
{ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); int ac = ieee80211_ac_from_tid(tid);
/* * If this AC is not trigger-enabled do nothing unless the * driver is calling us after it already checked. * * NB: This could/should check a separate bitmap of trigger- * enabled queues, but for now we only implement uAPSD w/o * TSPEC changes to the ACs, so they're always the same.
*/ if (!(sta->sta.uapsd_queues & ieee80211_ac_to_qos_mask[ac]) &&
tid != IEEE80211_NUM_TIDS) return;
/* if we are in a service period, do nothing */ if (test_sta_flag(sta, WLAN_STA_SP)) return;
if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
ieee80211_sta_ps_deliver_uapsd(sta); else
set_sta_flag(sta, WLAN_STA_UAPSD);
}
EXPORT_SYMBOL(ieee80211_sta_uapsd_trigger);
if (sdata->vif.type != NL80211_IFTYPE_AP &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN) return RX_CONTINUE;
/* * The device handles station powersave, so don't do anything about * uAPSD and PS-Poll frames (the latter shouldn't even come up from * it to mac80211 since they're handled.)
*/ if (ieee80211_hw_check(&sdata->local->hw, AP_LINK_PS)) return RX_CONTINUE;
/* * Don't do anything if the station isn't already asleep. In * the uAPSD case, the station will probably be marked asleep, * in the PS-Poll case the station must be confused ...
*/ if (!test_sta_flag(rx->sta, WLAN_STA_PS_STA)) return RX_CONTINUE;
if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) {
ieee80211_sta_pspoll(&rx->sta->sta);
/* Free PS Poll skb here instead of returning RX_DROP that would
* count as an dropped frame. */
dev_kfree_skb(rx->skb);
/* * Update last_rx only for IBSS packets which are for the current * BSSID and for station already AUTHORIZED to avoid keeping the * current IBSS network alive in cases where other STAs start * using different BSSID. This will also give the station another * chance to restart the authentication/authorization in case * something went wrong the first time.
*/ if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
NL80211_IFTYPE_ADHOC); if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) &&
test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
link_sta->rx_stats.last_rx = jiffies; if (ieee80211_is_data_present(hdr->frame_control) &&
!is_multicast_ether_addr(hdr->addr1))
link_sta->rx_stats.last_rate =
sta_stats_encode_rate(status);
}
} elseif (rx->sdata->vif.type == NL80211_IFTYPE_OCB) {
link_sta->rx_stats.last_rx = jiffies;
} elseif (!ieee80211_is_s1g_beacon(hdr->frame_control) &&
!is_multicast_ether_addr(hdr->addr1)) { /* * Mesh beacons will update last_rx when if they are found to * match the current local configuration when processed.
*/
link_sta->rx_stats.last_rx = jiffies; if (ieee80211_is_data_present(hdr->frame_control))
link_sta->rx_stats.last_rate = sta_stats_encode_rate(status);
}
if (status->chains) {
link_sta->rx_stats.chains = status->chains; for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) { int signal = status->chain_signal[i];
if (ieee80211_is_s1g_beacon(hdr->frame_control)) return RX_CONTINUE;
/* * Change STA power saving mode only at the end of a frame * exchange sequence, and only for a data or management * frame as specified in IEEE 802.11-2016 11.2.3.2
*/ if (!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS) &&
!ieee80211_has_morefrags(hdr->frame_control) &&
!is_multicast_ether_addr(hdr->addr1) &&
(ieee80211_is_mgmt(hdr->frame_control) ||
ieee80211_is_data(hdr->frame_control)) &&
!(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
(rx->sdata->vif.type == NL80211_IFTYPE_AP ||
rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { if (test_sta_flag(sta, WLAN_STA_PS_STA)) { if (!ieee80211_has_pm(hdr->frame_control))
sta_ps_end(sta);
} else { if (ieee80211_has_pm(hdr->frame_control))
sta_ps_start(sta);
}
}
/* mesh power save support */ if (ieee80211_vif_is_mesh(&rx->sdata->vif))
ieee80211_mps_rx_h_sta_process(sta, hdr);
/* * Drop (qos-)data::nullfunc frames silently, since they * are used only to control station power saving mode.
*/ if (ieee80211_is_any_nullfunc(hdr->frame_control)) {
I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc);
/* * If we receive a 4-addr nullfunc frame from a STA * that was not moved to a 4-addr STA vlan yet send * the event to userspace and for older hostapd drop * the frame to the monitor interface.
*/ if (ieee80211_has_a4(hdr->frame_control) &&
(rx->sdata->vif.type == NL80211_IFTYPE_AP ||
(rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
!rx->sdata->u.vlan.sta))) { if (!test_and_set_sta_flag(sta, WLAN_STA_4ADDR_EVENT))
cfg80211_rx_unexpected_4addr_frame(
rx->sdata->dev, sta->sta.addr,
rx->link_id, GFP_ATOMIC); return RX_DROP_U_UNEXPECTED_4ADDR_FRAME;
} /* * Update counter and free packet here to avoid * counting this as a dropped packed.
*/
link_sta->rx_stats.packets++;
dev_kfree_skb(rx->skb); return RX_QUEUED;
}
staticstruct ieee80211_key *
ieee80211_rx_get_bigtk(struct ieee80211_rx_data *rx, int idx)
{ struct ieee80211_key *key = NULL; int idx2;
/* Make sure key gets set if either BIGTK key index is set so that * ieee80211_drop_unencrypted_mgmt() can properly drop both unprotected * Beacon frames and Beacon frames that claim to use another BIGTK key * index (i.e., a key that we do not have).
*/
if (ieee80211_is_ext(hdr->frame_control)) return RX_CONTINUE;
/* * Key selection 101 * * There are five types of keys: * - GTK (group keys) * - IGTK (group keys for management frames) * - BIGTK (group keys for Beacon frames) * - PTK (pairwise keys) * - STK (station-to-station pairwise keys) * * When selecting a key, we have to distinguish between multicast * (including broadcast) and unicast frames, the latter can only * use PTKs and STKs while the former always use GTKs, IGTKs, and * BIGTKs. Unless, of course, actual WEP keys ("pre-RSNA") are used, * then unicast frames can also use key indices like GTKs. Hence, if we * don't have a PTK/STK we check the key index for a WEP key. * * Note that in a regular BSS, multicast frames are sent by the * AP only, associated stations unicast the frame to the AP first * which then multicasts it on their behalf. * * There is also a slight problem in IBSS mode: GTKs are negotiated * with each station, that is something we don't currently handle. * The spec seems to expect that one negotiates the same key with * every station but there's no such requirement; VLANs could be * possible.
*/
/* start without a key */
rx->key = NULL;
fc = hdr->frame_control;
if (rx->sta) { int keyid = rx->sta->ptk_idx;
sta_ptk = rcu_dereference(rx->sta->ptk[keyid]);
if (ieee80211_has_protected(fc) &&
!(status->flag & RX_FLAG_IV_STRIPPED)) {
keyid = ieee80211_get_keyid(rx->skb);
if (unlikely(keyid < 0)) return RX_DROP_U_NO_KEY_ID;
rx->key = ieee80211_rx_get_bigtk(rx, mmie_keyidx); if (!rx->key) return RX_CONTINUE; /* Beacon protection not in use */
} elseif (mmie_keyidx >= 0) { /* Broadcast/multicast robust management frame / BIP */ if ((status->flag & RX_FLAG_DECRYPTED) &&
(status->flag & RX_FLAG_IV_STRIPPED)) return RX_CONTINUE;
if (mmie_keyidx < NUM_DEFAULT_KEYS ||
mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) return RX_DROP_U_BAD_MGMT_KEYIDX; /* unexpected BIP keyidx */ if (rx->link_sta) { if (ieee80211_is_group_privacy_action(skb) &&
test_sta_flag(rx->sta, WLAN_STA_MFP)) return RX_DROP;
rx->key = rcu_dereference(rx->link_sta->gtk[mmie_keyidx]);
} if (!rx->key)
rx->key = rcu_dereference(rx->link->gtk[mmie_keyidx]);
} elseif (!ieee80211_has_protected(fc)) { /* * The frame was not protected, so skip decryption. However, we * need to set rx->key if there is a key that could have been * used so that the frame may be dropped if encryption would * have been expected.
*/ struct ieee80211_key *key = NULL; int i;
if (ieee80211_is_beacon(fc)) {
key = ieee80211_rx_get_bigtk(rx, -1);
} elseif (ieee80211_is_mgmt(fc) &&
is_multicast_ether_addr(hdr->addr1)) {
key = rcu_dereference(rx->link->default_mgmt_key);
} else { if (rx->link_sta) { for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
key = rcu_dereference(rx->link_sta->gtk[i]); if (key) break;
}
} if (!key) { for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
key = rcu_dereference(rx->link->gtk[i]); if (key) break;
}
}
} if (key)
rx->key = key; return RX_CONTINUE;
} else { /* * The device doesn't give us the IV so we won't be * able to look up the key. That's ok though, we * don't need to decrypt the frame, we just won't * be able to keep statistics accurate. * Except for key threshold notifications, should * we somehow allow the driver to tell us which key * the hardware used if this flag is set?
*/ if ((status->flag & RX_FLAG_DECRYPTED) &&
(status->flag & RX_FLAG_IV_STRIPPED)) return RX_CONTINUE;
keyidx = ieee80211_get_keyid(rx->skb);
if (unlikely(keyidx < 0)) return RX_DROP_U_NO_KEY_ID;
/* check per-station GTK first, if multicast packet */ if (is_multicast_ether_addr(hdr->addr1) && rx->link_sta)
rx->key = rcu_dereference(rx->link_sta->gtk[keyidx]);
/* if not found, try default key */ if (!rx->key) { if (is_multicast_ether_addr(hdr->addr1))
rx->key = rcu_dereference(rx->link->gtk[keyidx]); if (!rx->key)
rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
/* * RSNA-protected unicast frames should always be * sent with pairwise or station-to-station keys, * but for WEP we allow using a key index as well.
*/ if (rx->key &&
rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 &&
rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 &&
!is_multicast_ether_addr(hdr->addr1))
rx->key = NULL;
}
}
if (rx->key) { if (unlikely(rx->key->flags & KEY_FLAG_TAINTED)) return RX_DROP;
switch (rx->key->conf.cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104:
result = ieee80211_crypto_wep_decrypt(rx); break; case WLAN_CIPHER_SUITE_TKIP:
result = ieee80211_crypto_tkip_decrypt(rx); break; case WLAN_CIPHER_SUITE_CCMP:
result = ieee80211_crypto_ccmp_decrypt(
rx, IEEE80211_CCMP_MIC_LEN); break; case WLAN_CIPHER_SUITE_CCMP_256:
result = ieee80211_crypto_ccmp_decrypt(
rx, IEEE80211_CCMP_256_MIC_LEN); break; case WLAN_CIPHER_SUITE_AES_CMAC:
result = ieee80211_crypto_aes_cmac_decrypt(rx); break; case WLAN_CIPHER_SUITE_BIP_CMAC_256:
result = ieee80211_crypto_aes_cmac_256_decrypt(rx); break; case WLAN_CIPHER_SUITE_BIP_GMAC_128: case WLAN_CIPHER_SUITE_BIP_GMAC_256:
result = ieee80211_crypto_aes_gmac_decrypt(rx); break; case WLAN_CIPHER_SUITE_GCMP: case WLAN_CIPHER_SUITE_GCMP_256:
result = ieee80211_crypto_gcmp_decrypt(rx); break; default:
result = RX_DROP_U_BAD_CIPHER;
}
/* the hdr variable is invalid after the decrypt handlers */
/* either the frame has been decrypted or will be dropped */
status->flag |= RX_FLAG_DECRYPTED;
if (unlikely(ieee80211_is_beacon(fc) && RX_RES_IS_UNUSABLE(result) &&
rx->sdata->dev))
cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
skb->data, skb->len);
return result;
}
void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache)
{ int i;
for (i = 0; i < ARRAY_SIZE(cache->entries); i++)
skb_queue_head_init(&cache->entries[i].skb_list);
}
void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache)
{ int i;
for (i = 0; i < ARRAY_SIZE(cache->entries); i++)
__skb_queue_purge(&cache->entries[i].skb_list);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.