diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3a1e2c9e1565..ee792b77a8c6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3877,6 +3877,38 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, return true; } +static bool ieee80211_drop_unauth_port(struct ieee80211_tx_data *tx) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); + struct ieee80211_hdr *hdr; + + if (likely(test_sta_flag(tx->sta, WLAN_STA_AUTHORIZED))) + return false; + + if (info->flags & IEEE80211_TX_CTL_INJECTED) + return false; + + if (ieee80211_vif_is_mesh(&tx->sdata->vif) || + tx->sdata->vif.type == NL80211_IFTYPE_OCB) + return false; + + /* no need to check forwarding here */ + if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) + return !(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO); + + hdr = (struct ieee80211_hdr *)tx->skb->data; + + if (!ieee80211_is_data_present(hdr->frame_control) || + is_multicast_ether_addr(hdr->addr1)) + return false; + + if ((info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) && + ieee80211_is_our_addr(tx->sdata, hdr->addr2, NULL)) + return false; + + return true; +} + struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { @@ -3943,20 +3975,8 @@ begin: if (txq->sta) { tx.sta = container_of(txq->sta, struct sta_info, sta); - /* - * Drop unicast frames to unauthorised stations unless they are - * injected frames or EAPOL frames from the local station. - */ - if (unlikely(!(info->flags & IEEE80211_TX_CTL_INJECTED) && - ieee80211_is_data_present(hdr->frame_control) && - !ieee80211_vif_is_mesh(&tx.sdata->vif) && - tx.sdata->vif.type != NL80211_IFTYPE_OCB && - !is_multicast_ether_addr(hdr->addr1) && - !test_sta_flag(tx.sta, WLAN_STA_AUTHORIZED) && - (!(info->control.flags & - IEEE80211_TX_CTRL_PORT_CTRL_PROTO) || - !ieee80211_is_our_addr(tx.sdata, hdr->addr2, - NULL)))) { + + if (unlikely(ieee80211_drop_unauth_port(&tx))) { I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); ieee80211_free_txskb(&local->hw, skb); goto begin;