Commit a621fa4d6a7fdf9d34938d2e129a72624833eeeb

Authored by Johannes Berg
Committed by John W. Linville
1 parent c0692b8fe2

mac80211: allow changing port control protocol

Some vendor specified mechanisms for 802.1X-style
functionality use a different protocol than EAP
(even if EAP is vendor-extensible). Support this
in mac80211 via the cfg80211 API for it.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

Showing 6 changed files with 29 additions and 4 deletions Side-by-side Diff

net/mac80211/ieee80211_i.h
... ... @@ -509,6 +509,8 @@
509 509 struct ieee80211_key *default_mgmt_key;
510 510  
511 511 u16 sequence_number;
  512 + __be16 control_port_protocol;
  513 + bool control_port_no_encrypt;
512 514  
513 515 struct work_struct work;
514 516 struct sk_buff_head skb_queue;
net/mac80211/iface.c
... ... @@ -855,6 +855,9 @@
855 855 sdata->dev->netdev_ops = &ieee80211_dataif_ops;
856 856 sdata->wdev.iftype = type;
857 857  
  858 + sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
  859 + sdata->control_port_no_encrypt = false;
  860 +
858 861 /* only monitor differs */
859 862 sdata->dev->type = ARPHRD_ETHER;
860 863  
... ... @@ -627,6 +627,9 @@
627 627 local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT);
628 628 #endif
629 629  
  630 + /* mac80211 supports control port protocol changing */
  631 + local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL;
  632 +
630 633 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
631 634 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
632 635 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
... ... @@ -2262,6 +2262,9 @@
2262 2262 else
2263 2263 ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
2264 2264  
  2265 + sdata->control_port_protocol = req->crypto.control_port_ethertype;
  2266 + sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
  2267 +
2265 2268 ieee80211_add_work(wk);
2266 2269 return 0;
2267 2270 }
... ... @@ -1527,7 +1527,7 @@
1527 1527 * Allow EAPOL frames to us/the PAE group address regardless
1528 1528 * of whether the frame was encrypted or not.
1529 1529 */
1530   - if (ehdr->h_proto == htons(ETH_P_PAE) &&
  1530 + if (ehdr->h_proto == rx->sdata->control_port_protocol &&
1531 1531 (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 ||
1532 1532 compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0))
1533 1533 return true;
... ... @@ -509,6 +509,18 @@
509 509 }
510 510  
511 511 static ieee80211_tx_result debug_noinline
  512 +ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx)
  513 +{
  514 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
  515 +
  516 + if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol &&
  517 + tx->sdata->control_port_no_encrypt))
  518 + info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
  519 +
  520 + return TX_CONTINUE;
  521 +}
  522 +
  523 +static ieee80211_tx_result debug_noinline
512 524 ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
513 525 {
514 526 struct ieee80211_key *key = NULL;
... ... @@ -527,7 +539,7 @@
527 539 else if ((key = rcu_dereference(tx->sdata->default_key)))
528 540 tx->key = key;
529 541 else if (tx->sdata->drop_unencrypted &&
530   - (tx->skb->protocol != cpu_to_be16(ETH_P_PAE)) &&
  542 + (tx->skb->protocol != tx->sdata->control_port_protocol) &&
531 543 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
532 544 (!ieee80211_is_robust_mgmt_frame(hdr) ||
533 545 (ieee80211_is_action(hdr->frame_control) &&
... ... @@ -1349,6 +1361,7 @@
1349 1361 CALL_TXH(ieee80211_tx_h_dynamic_ps);
1350 1362 CALL_TXH(ieee80211_tx_h_check_assoc);
1351 1363 CALL_TXH(ieee80211_tx_h_ps_buf);
  1364 + CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
1352 1365 CALL_TXH(ieee80211_tx_h_select_key);
1353 1366 if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
1354 1367 CALL_TXH(ieee80211_tx_h_rate_ctrl);
... ... @@ -1826,7 +1839,8 @@
1826 1839 #endif
1827 1840 case NL80211_IFTYPE_STATION:
1828 1841 memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
1829   - if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) {
  1842 + if (sdata->u.mgd.use_4addr &&
  1843 + cpu_to_be16(ethertype) != sdata->control_port_protocol) {
1830 1844 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1831 1845 /* RA TA DA SA */
1832 1846 memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
... ... @@ -1879,7 +1893,7 @@
1879 1893 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
1880 1894 unlikely(!is_multicast_ether_addr(hdr.addr1) &&
1881 1895 !(sta_flags & WLAN_STA_AUTHORIZED) &&
1882   - !(ethertype == ETH_P_PAE &&
  1896 + !(cpu_to_be16(ethertype) == sdata->control_port_protocol &&
1883 1897 compare_ether_addr(sdata->vif.addr,
1884 1898 skb->data + ETH_ALEN) == 0))) {
1885 1899 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG