If userspace requested control port frames to go over 80211, then do so. The control packets are intercepted just prior to delivery of the packet to the underlying network device. Signed-off-by: Denis Kenzior <denkenz@xxxxxxxxx> --- net/mac80211/rx.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b3cff69bfd66..13e786fe62a6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2326,16 +2326,42 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) } #endif - if (skb) { + if (!skb) + goto try_xmit; + + skb->protocol = eth_type_trans(skb, dev); + memset(skb->cb, 0, sizeof(skb->cb)); + + if (unlikely(skb->protocol == sdata->control_port_protocol && + sdata->control_port_over_nl80211)) { + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + bool noencrypt; + + ehdr = eth_hdr(skb); + + if (status->flag & RX_FLAG_DECRYPTED) + noencrypt = false; + else + noencrypt = true; + + if (!cfg80211_rx_control_port(&sdata->wdev, + skb->data, + skb->len, + ehdr->h_source, + be16_to_cpu(skb->protocol), + noencrypt)) { + dev_kfree_skb(skb); + skb = NULL; + } + } else { /* deliver to local stack */ - skb->protocol = eth_type_trans(skb, dev); - memset(skb->cb, 0, sizeof(skb->cb)); if (rx->napi) napi_gro_receive(rx->napi, skb); else netif_receive_skb(skb); } +try_xmit: if (xmit_skb) { /* * Send to wireless media and increase priority by 256 to -- 2.13.5