Commit 98f0b0a3 authored by Ron Rindjunsky's avatar Ron Rindjunsky Committed by David S. Miller
Browse files

mac80211: pass in PS_POLL frames



This patch fixes should_drop_frame function to pass in ps poll control
frames required for power save functioanlity. Interface types that do not
have interest for PS POLL frames now drop it in handler.
Signed-off-by: default avatarRon Rindjunsky <ron.rindjunsky@intel.com>
Acked-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d647b36a
...@@ -61,8 +61,10 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, ...@@ -61,8 +61,10 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status,
return 1; return 1;
if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len))
return 1; return 1;
if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == if (((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
cpu_to_le16(IEEE80211_FTYPE_CTL)) cpu_to_le16(IEEE80211_FTYPE_CTL)) &&
((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) !=
cpu_to_le16(IEEE80211_STYPE_PSPOLL)))
return 1; return 1;
return 0; return 0;
} }
...@@ -896,6 +898,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) ...@@ -896,6 +898,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx)
static ieee80211_txrx_result static ieee80211_txrx_result
ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
struct sk_buff *skb; struct sk_buff *skb;
int no_pending_pkts; int no_pending_pkts;
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
...@@ -906,6 +909,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) ...@@ -906,6 +909,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx)
!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))) !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)))
return TXRX_CONTINUE; return TXRX_CONTINUE;
if ((sdata->type != IEEE80211_IF_TYPE_AP) &&
(sdata->type != IEEE80211_IF_TYPE_VLAN))
return TXRX_DROP;
skb = skb_dequeue(&rx->sta->tx_filtered); skb = skb_dequeue(&rx->sta->tx_filtered);
if (!skb) { if (!skb) {
skb = skb_dequeue(&rx->sta->ps_tx_buf); skb = skb_dequeue(&rx->sta->ps_tx_buf);
......
...@@ -135,13 +135,16 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len) ...@@ -135,13 +135,16 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len)
{ {
u16 fc; u16 fc;
if (len < 24) /* drop ACK/CTS frames and incorrect hdr len (ctrl) */
if (len < 16)
return NULL; return NULL;
fc = le16_to_cpu(hdr->frame_control); fc = le16_to_cpu(hdr->frame_control);
switch (fc & IEEE80211_FCTL_FTYPE) { switch (fc & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_DATA: case IEEE80211_FTYPE_DATA:
if (len < 24) /* drop incorrect hdr len (data) */
return NULL;
switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
case IEEE80211_FCTL_TODS: case IEEE80211_FCTL_TODS:
return hdr->addr1; return hdr->addr1;
...@@ -154,6 +157,8 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len) ...@@ -154,6 +157,8 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len)
} }
break; break;
case IEEE80211_FTYPE_MGMT: case IEEE80211_FTYPE_MGMT:
if (len < 24) /* drop incorrect hdr len (mgmt) */
return NULL;
return hdr->addr3; return hdr->addr3;
case IEEE80211_FTYPE_CTL: case IEEE80211_FTYPE_CTL:
if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL) if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)
......
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