diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 007f5a368d41..e5c0204d05b6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1080,6 +1080,33 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) return TX_DROP; } +struct sk_buff *ieee80211_encrypt_tx_skb(struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_data tx; + + if (!info->control.hw_key) + return skb; + + memset(&tx, 0, sizeof(tx)); + tx.key = container_of(info->control.hw_key, struct ieee80211_key, conf); + /* NULL it out now so we do full SW crypto */ + info->control.hw_key = NULL; + __skb_queue_head_init(&tx->skbs); + __skb_queue_tail(&tx->skbs, skb); + /* FIXME: tx.local/tx.sdata are not used now, set anyway? */ + + if (ieee80211_tx_h_encrypt(&tx) != TX_CONTINUE) + return NULL; + if (WARN_ON_ONCE(skb_queue_len(&tx->skbs) != 1)) { + __skb_queue_purge(&tx->skbs); + return NULL; + } + + return __skb_dequeue(&tx->skbs); +} +EXPORT_SYMBOL_GPL(ieee80211_encrypt_tx_skb); + static ieee80211_tx_result debug_noinline ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) {