Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: Documentation/feature-removal-schedule.txt drivers/net/wireless/ath/ath5k/phy.c drivers/net/wireless/wl12xx/wl1271_main.c
This commit is contained in:
@@ -39,7 +39,7 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
|
||||
{
|
||||
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
|
||||
if (likely(skb->len > FCS_LEN))
|
||||
skb_trim(skb, skb->len - FCS_LEN);
|
||||
__pskb_trim(skb, skb->len - FCS_LEN);
|
||||
else {
|
||||
/* driver bug */
|
||||
WARN_ON(1);
|
||||
@@ -228,6 +228,12 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
||||
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
|
||||
present_fcs_len = FCS_LEN;
|
||||
|
||||
/* make sure hdr->frame_control is on the linear part */
|
||||
if (!pskb_may_pull(origskb, 2)) {
|
||||
dev_kfree_skb(origskb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!local->monitors) {
|
||||
if (should_drop_frame(origskb, present_fcs_len)) {
|
||||
dev_kfree_skb(origskb);
|
||||
@@ -485,7 +491,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
|
||||
|
||||
if (ieee80211_is_action(hdr->frame_control)) {
|
||||
mgmt = (struct ieee80211_mgmt *)hdr;
|
||||
if (mgmt->u.action.category != MESH_PLINK_CATEGORY)
|
||||
if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK)
|
||||
return RX_DROP_MONITOR;
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
@@ -715,14 +721,16 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
|
||||
|
||||
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
|
||||
|
||||
if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL)
|
||||
goto dont_reorder;
|
||||
spin_lock(&sta->lock);
|
||||
|
||||
if (!sta->ampdu_mlme.tid_active_rx[tid])
|
||||
goto dont_reorder_unlock;
|
||||
|
||||
tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
|
||||
|
||||
/* qos null data frames are excluded */
|
||||
if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
|
||||
goto dont_reorder;
|
||||
goto dont_reorder_unlock;
|
||||
|
||||
/* new, potentially un-ordered, ampdu frame - process it */
|
||||
|
||||
@@ -734,15 +742,20 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
|
||||
/* if this mpdu is fragmented - terminate rx aggregation session */
|
||||
sc = le16_to_cpu(hdr->seq_ctrl);
|
||||
if (sc & IEEE80211_SCTL_FRAG) {
|
||||
ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
|
||||
tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP);
|
||||
spin_unlock(&sta->lock);
|
||||
__ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
|
||||
WLAN_REASON_QSTA_REQUIRE_SETUP);
|
||||
dev_kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames))
|
||||
if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) {
|
||||
spin_unlock(&sta->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
dont_reorder_unlock:
|
||||
spin_unlock(&sta->lock);
|
||||
dont_reorder:
|
||||
__skb_queue_tail(frames, skb);
|
||||
}
|
||||
@@ -889,6 +902,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||
rx->key = key;
|
||||
return RX_CONTINUE;
|
||||
} else {
|
||||
u8 keyid;
|
||||
/*
|
||||
* The device doesn't give us the IV so we won't be
|
||||
* able to look up the key. That's ok though, we
|
||||
@@ -911,7 +925,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||
* no need to call ieee80211_wep_get_keyidx,
|
||||
* it verifies a bunch of things we've done already
|
||||
*/
|
||||
keyidx = rx->skb->data[hdrlen + 3] >> 6;
|
||||
skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
|
||||
keyidx = keyid >> 6;
|
||||
|
||||
rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
|
||||
|
||||
@@ -932,6 +947,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
||||
return RX_DROP_MONITOR;
|
||||
}
|
||||
|
||||
if (skb_linearize(rx->skb))
|
||||
return RX_DROP_UNUSABLE;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)rx->skb->data;
|
||||
|
||||
/* Check for weak IVs if possible */
|
||||
if (rx->sta && rx->key->conf.alg == ALG_WEP &&
|
||||
ieee80211_is_data(hdr->frame_control) &&
|
||||
@@ -1232,6 +1252,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
||||
}
|
||||
I802_DEBUG_INC(rx->local->rx_handlers_fragments);
|
||||
|
||||
if (skb_linearize(rx->skb))
|
||||
return RX_DROP_UNUSABLE;
|
||||
|
||||
seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
|
||||
|
||||
if (frag == 0) {
|
||||
@@ -1397,21 +1420,24 @@ static int
|
||||
ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||
__le16 fc = hdr->frame_control;
|
||||
int res;
|
||||
|
||||
res = ieee80211_drop_unencrypted(rx, fc);
|
||||
if (unlikely(res))
|
||||
return res;
|
||||
/*
|
||||
* Pass through unencrypted frames if the hardware has
|
||||
* decrypted them already.
|
||||
*/
|
||||
if (status->flag & RX_FLAG_DECRYPTED)
|
||||
return 0;
|
||||
|
||||
if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
|
||||
if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
|
||||
if (unlikely(!ieee80211_has_protected(fc) &&
|
||||
ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
|
||||
rx->key))
|
||||
return -EACCES;
|
||||
/* BIP does not use Protected field, so need to check MMIE */
|
||||
if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
|
||||
ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
|
||||
rx->key))
|
||||
ieee80211_get_mmie_keyidx(rx->skb) < 0))
|
||||
return -EACCES;
|
||||
/*
|
||||
* When using MFP, Action frames are not allowed prior to
|
||||
@@ -1589,6 +1615,9 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
|
||||
skb->dev = dev;
|
||||
__skb_queue_head_init(&frame_list);
|
||||
|
||||
if (skb_linearize(skb))
|
||||
return RX_DROP_UNUSABLE;
|
||||
|
||||
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
|
||||
rx->sdata->vif.type,
|
||||
rx->local->hw.extra_tx_headroom);
|
||||
@@ -1787,10 +1816,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
|
||||
if (ieee80211_is_back_req(bar->frame_control)) {
|
||||
if (!rx->sta)
|
||||
return RX_DROP_MONITOR;
|
||||
spin_lock(&rx->sta->lock);
|
||||
tid = le16_to_cpu(bar->control) >> 12;
|
||||
if (rx->sta->ampdu_mlme.tid_state_rx[tid]
|
||||
!= HT_AGG_STATE_OPERATIONAL)
|
||||
if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) {
|
||||
spin_unlock(&rx->sta->lock);
|
||||
return RX_DROP_MONITOR;
|
||||
}
|
||||
tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
|
||||
|
||||
start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
|
||||
@@ -1804,6 +1835,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
|
||||
ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
|
||||
frames);
|
||||
kfree_skb(skb);
|
||||
spin_unlock(&rx->sta->lock);
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
||||
@@ -1965,8 +1997,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
||||
goto handled;
|
||||
}
|
||||
break;
|
||||
case MESH_PLINK_CATEGORY:
|
||||
case MESH_PATH_SEL_CATEGORY:
|
||||
case WLAN_CATEGORY_MESH_PLINK:
|
||||
case WLAN_CATEGORY_MESH_PATH_SEL:
|
||||
if (ieee80211_vif_is_mesh(&sdata->vif))
|
||||
return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
|
||||
break;
|
||||
@@ -2363,29 +2395,42 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_hdr *hdr;
|
||||
__le16 fc;
|
||||
struct ieee80211_rx_data rx;
|
||||
int prepares;
|
||||
struct ieee80211_sub_if_data *prev = NULL;
|
||||
struct sk_buff *skb_new;
|
||||
struct sta_info *sta, *tmp;
|
||||
bool found_sta = false;
|
||||
int err = 0;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
|
||||
memset(&rx, 0, sizeof(rx));
|
||||
rx.skb = skb;
|
||||
rx.local = local;
|
||||
|
||||
if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control))
|
||||
if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
|
||||
local->dot11ReceivedFragmentCount++;
|
||||
|
||||
if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
|
||||
test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
|
||||
rx.flags |= IEEE80211_RX_IN_SCAN;
|
||||
|
||||
if (ieee80211_is_mgmt(fc))
|
||||
err = skb_linearize(skb);
|
||||
else
|
||||
err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
|
||||
|
||||
if (err) {
|
||||
dev_kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
ieee80211_parse_qos(&rx);
|
||||
ieee80211_verify_alignment(&rx);
|
||||
|
||||
if (ieee80211_is_data(hdr->frame_control)) {
|
||||
if (ieee80211_is_data(fc)) {
|
||||
for_each_sta_info(local, hdr->addr2, sta, tmp) {
|
||||
rx.sta = sta;
|
||||
found_sta = true;
|
||||
|
مرجع در شماره جدید
Block a user