diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-08-27 07:26:54 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-27 13:27:07 -0400 |
commit | a621fa4d6a7fdf9d34938d2e129a72624833eeeb (patch) | |
tree | 1b15e9fabbec3b2bdf04f5cd60526c0154a0dcc1 | |
parent | c0692b8fe29fb4d4dad33487aabf3ed7e1e880c0 (diff) |
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>
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 3 | ||||
-rw-r--r-- | net/mac80211/rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 20 |
6 files changed, 29 insertions, 4 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 7d2bb6fbc2e6..f64837788681 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -509,6 +509,8 @@ struct ieee80211_sub_if_data { | |||
509 | struct ieee80211_key *default_mgmt_key; | 509 | struct ieee80211_key *default_mgmt_key; |
510 | 510 | ||
511 | u16 sequence_number; | 511 | u16 sequence_number; |
512 | __be16 control_port_protocol; | ||
513 | bool control_port_no_encrypt; | ||
512 | 514 | ||
513 | struct work_struct work; | 515 | struct work_struct work; |
514 | struct sk_buff_head skb_queue; | 516 | struct sk_buff_head skb_queue; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 9369710cc65b..810e6764d04f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -855,6 +855,9 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
855 | sdata->dev->netdev_ops = &ieee80211_dataif_ops; | 855 | sdata->dev->netdev_ops = &ieee80211_dataif_ops; |
856 | sdata->wdev.iftype = type; | 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 | /* only monitor differs */ | 861 | /* only monitor differs */ |
859 | sdata->dev->type = ARPHRD_ETHER; | 862 | sdata->dev->type = ARPHRD_ETHER; |
860 | 863 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 15f0e960fde8..964c267163a0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -627,6 +627,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
627 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); | 627 | local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); |
628 | #endif | 628 | #endif |
629 | 629 | ||
630 | /* mac80211 supports control port protocol changing */ | ||
631 | local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; | ||
632 | |||
630 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 633 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
631 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 634 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
632 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) | 635 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5282ac18d2cf..0cb429657474 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2262,6 +2262,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2262 | else | 2262 | else |
2263 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; | 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 | ieee80211_add_work(wk); | 2268 | ieee80211_add_work(wk); |
2266 | return 0; | 2269 | return 0; |
2267 | } | 2270 | } |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6e5fb16af55c..ac205a33690f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1527,7 +1527,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) | |||
1527 | * Allow EAPOL frames to us/the PAE group address regardless | 1527 | * Allow EAPOL frames to us/the PAE group address regardless |
1528 | * of whether the frame was encrypted or not. | 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 | (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || | 1531 | (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || |
1532 | compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) | 1532 | compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) |
1533 | return true; | 1533 | return true; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 31a8903a45af..92764bb8795c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -509,6 +509,18 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | |||
509 | } | 509 | } |
510 | 510 | ||
511 | static ieee80211_tx_result debug_noinline | 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 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | 524 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) |
513 | { | 525 | { |
514 | struct ieee80211_key *key = NULL; | 526 | struct ieee80211_key *key = NULL; |
@@ -527,7 +539,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
527 | else if ((key = rcu_dereference(tx->sdata->default_key))) | 539 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
528 | tx->key = key; | 540 | tx->key = key; |
529 | else if (tx->sdata->drop_unencrypted && | 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 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | 543 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && |
532 | (!ieee80211_is_robust_mgmt_frame(hdr) || | 544 | (!ieee80211_is_robust_mgmt_frame(hdr) || |
533 | (ieee80211_is_action(hdr->frame_control) && | 545 | (ieee80211_is_action(hdr->frame_control) && |
@@ -1349,6 +1361,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1349 | CALL_TXH(ieee80211_tx_h_dynamic_ps); | 1361 | CALL_TXH(ieee80211_tx_h_dynamic_ps); |
1350 | CALL_TXH(ieee80211_tx_h_check_assoc); | 1362 | CALL_TXH(ieee80211_tx_h_check_assoc); |
1351 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1363 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1364 | CALL_TXH(ieee80211_tx_h_check_control_port_protocol); | ||
1352 | CALL_TXH(ieee80211_tx_h_select_key); | 1365 | CALL_TXH(ieee80211_tx_h_select_key); |
1353 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) | 1366 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) |
1354 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | 1367 | CALL_TXH(ieee80211_tx_h_rate_ctrl); |
@@ -1826,7 +1839,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1826 | #endif | 1839 | #endif |
1827 | case NL80211_IFTYPE_STATION: | 1840 | case NL80211_IFTYPE_STATION: |
1828 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 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 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1844 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1831 | /* RA TA DA SA */ | 1845 | /* RA TA DA SA */ |
1832 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); | 1846 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); |
@@ -1879,7 +1893,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1879 | if (!ieee80211_vif_is_mesh(&sdata->vif) && | 1893 | if (!ieee80211_vif_is_mesh(&sdata->vif) && |
1880 | unlikely(!is_multicast_ether_addr(hdr.addr1) && | 1894 | unlikely(!is_multicast_ether_addr(hdr.addr1) && |
1881 | !(sta_flags & WLAN_STA_AUTHORIZED) && | 1895 | !(sta_flags & WLAN_STA_AUTHORIZED) && |
1882 | !(ethertype == ETH_P_PAE && | 1896 | !(cpu_to_be16(ethertype) == sdata->control_port_protocol && |
1883 | compare_ether_addr(sdata->vif.addr, | 1897 | compare_ether_addr(sdata->vif.addr, |
1884 | skb->data + ETH_ALEN) == 0))) { | 1898 | skb->data + ETH_ALEN) == 0))) { |
1885 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1899 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |