aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-27 07:26:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-27 13:27:07 -0400
commita621fa4d6a7fdf9d34938d2e129a72624833eeeb (patch)
tree1b15e9fabbec3b2bdf04f5cd60526c0154a0dcc1
parentc0692b8fe29fb4d4dad33487aabf3ed7e1e880c0 (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.h2
-rw-r--r--net/mac80211/iface.c3
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mlme.c3
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/tx.c20
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
511static ieee80211_tx_result debug_noinline 511static ieee80211_tx_result debug_noinline
512ieee80211_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
523static ieee80211_tx_result debug_noinline
512ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) 524ieee80211_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