Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: Send control port frames over nl80211

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.

Pre-authentication type frames (protocol: 0x88c7) are also forwarded
over nl80211.

Signed-off-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Denis Kenzior and committed by
Johannes Berg
018f6fbf 91180649

+42 -5
+6
net/mac80211/cfg.c
··· 926 926 */ 927 927 sdata->control_port_protocol = params->crypto.control_port_ethertype; 928 928 sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; 929 + sdata->control_port_over_nl80211 = 930 + params->crypto.control_port_over_nl80211; 929 931 sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local, 930 932 &params->crypto, 931 933 sdata->vif.type); ··· 937 935 params->crypto.control_port_ethertype; 938 936 vlan->control_port_no_encrypt = 939 937 params->crypto.control_port_no_encrypt; 938 + vlan->control_port_over_nl80211 = 939 + params->crypto.control_port_over_nl80211; 940 940 vlan->encrypt_headroom = 941 941 ieee80211_cs_headroom(sdata->local, 942 942 &params->crypto, ··· 2023 2019 err = copy_mesh_setup(ifmsh, setup); 2024 2020 if (err) 2025 2021 return err; 2022 + 2023 + sdata->control_port_over_nl80211 = setup->control_port_over_nl80211; 2026 2024 2027 2025 /* can mesh use other SMPS modes? */ 2028 2026 sdata->smps_mode = IEEE80211_SMPS_OFF;
+1
net/mac80211/ibss.c
··· 1844 1844 1845 1845 sdata->smps_mode = IEEE80211_SMPS_OFF; 1846 1846 sdata->needed_rx_chains = local->rx_chains; 1847 + sdata->control_port_over_nl80211 = params->control_port_over_nl80211; 1847 1848 1848 1849 ieee80211_queue_work(&local->hw, &sdata->work); 1849 1850
+1
net/mac80211/ieee80211_i.h
··· 900 900 u16 sequence_number; 901 901 __be16 control_port_protocol; 902 902 bool control_port_no_encrypt; 903 + bool control_port_over_nl80211; 903 904 int encrypt_headroom; 904 905 905 906 atomic_t num_tx_queued;
+2
net/mac80211/iface.c
··· 519 519 master->control_port_protocol; 520 520 sdata->control_port_no_encrypt = 521 521 master->control_port_no_encrypt; 522 + sdata->control_port_over_nl80211 = 523 + master->control_port_over_nl80211; 522 524 sdata->vif.cab_queue = master->vif.cab_queue; 523 525 memcpy(sdata->vif.hw_queue, master->vif.hw_queue, 524 526 sizeof(sdata->vif.hw_queue));
+2
net/mac80211/main.c
··· 554 554 NL80211_FEATURE_USERSPACE_MPM | 555 555 NL80211_FEATURE_FULL_AP_CLIENT_STATE; 556 556 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); 557 + wiphy_ext_feature_set(wiphy, 558 + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); 557 559 558 560 if (!ops->hw_scan) 559 561 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
+2
net/mac80211/mlme.c
··· 4855 4855 4856 4856 sdata->control_port_protocol = req->crypto.control_port_ethertype; 4857 4857 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; 4858 + sdata->control_port_over_nl80211 = 4859 + req->crypto.control_port_over_nl80211; 4858 4860 sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto, 4859 4861 sdata->vif.type); 4860 4862
+28 -5
net/mac80211/rx.c
··· 2245 2245 return true; 2246 2246 } 2247 2247 2248 + static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, 2249 + struct ieee80211_rx_data *rx) 2250 + { 2251 + struct ieee80211_sub_if_data *sdata = rx->sdata; 2252 + struct net_device *dev = sdata->dev; 2253 + 2254 + if (unlikely((skb->protocol == sdata->control_port_protocol || 2255 + skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) && 2256 + sdata->control_port_over_nl80211)) { 2257 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 2258 + bool noencrypt = status->flag & RX_FLAG_DECRYPTED; 2259 + struct ethhdr *ehdr = eth_hdr(skb); 2260 + 2261 + cfg80211_rx_control_port(dev, skb->data, skb->len, 2262 + ehdr->h_source, 2263 + be16_to_cpu(skb->protocol), noencrypt); 2264 + dev_kfree_skb(skb); 2265 + } else { 2266 + /* deliver to local stack */ 2267 + if (rx->napi) 2268 + napi_gro_receive(rx->napi, skb); 2269 + else 2270 + netif_receive_skb(skb); 2271 + } 2272 + } 2273 + 2248 2274 /* 2249 2275 * requires that rx->skb is a frame with ethernet header 2250 2276 */ ··· 2355 2329 #endif 2356 2330 2357 2331 if (skb) { 2358 - /* deliver to local stack */ 2359 2332 skb->protocol = eth_type_trans(skb, dev); 2360 2333 memset(skb->cb, 0, sizeof(skb->cb)); 2361 - if (rx->napi) 2362 - napi_gro_receive(rx->napi, skb); 2363 - else 2364 - netif_receive_skb(skb); 2334 + 2335 + ieee80211_deliver_skb_to_local_stack(skb, rx); 2365 2336 } 2366 2337 2367 2338 if (xmit_skb) {