aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-03-19 07:39:22 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-27 20:13:02 -0400
commit636a5d3625993c5ca59abc81794b9ded93cdb740 (patch)
tree53ee8d522153c36c631f8cb733a6e808c20ef332 /net/mac80211/mlme.c
parent6039f6d23fe792d615da5449e9fa1c6b43caacf6 (diff)
nl80211: Add MLME primitives to support external SME
This patch adds new nl80211 commands to allow user space to request authentication and association (and also deauthentication and disassociation). The commands are structured to allow separate authentication and association steps, i.e., the interface between kernel and user space is similar to the MLME SAP interface in IEEE 802.11 standard and an user space application takes the role of the SME. The patch introduces MLME-AUTHENTICATE.request, MLME-{,RE}ASSOCIATE.request, MLME-DEAUTHENTICATE.request, and MLME-DISASSOCIATE.request primitives. The authentication and association commands request the actual operations in two steps (assuming the driver supports this; if not, separate authentication step is skipped; this could end up being a separate "connect" command). The initial implementation for mac80211 uses the current net/mac80211/mlme.c for actual sending and processing of management frames and the new nl80211 commands will just stop the current state machine from moving automatically from authentication to association. Future cleanup may move more of the MLME operations into cfg80211. The goal of this design is to provide more control of authentication and association process to user space without having to move the full MLME implementation. This should be enough to allow IEEE 802.11r FT protocol and 802.11s SAE authentication to be implemented. Obviously, this will also bring the extra benefit of not having to use WEXT for association requests with mac80211. An example implementation of a user space SME using the new nl80211 commands is available for wpa_supplicant. This patch is enough to get IEEE 802.11r FT protocol working with over-the-air mechanism (over-the-DS will need additional MLME primitives for handling the FT Action frames). Signed-off-by: Jouni Malinen <j@w1.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6dc7a61bc18b..d1bcc8438772 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -730,6 +730,8 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
730{ 730{
731 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 731 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
732 struct ieee80211_local *local = sdata->local; 732 struct ieee80211_local *local = sdata->local;
733 u8 *ies;
734 size_t ies_len;
733 735
734 ifmgd->auth_tries++; 736 ifmgd->auth_tries++;
735 if (ifmgd->auth_tries > IEEE80211_AUTH_MAX_TRIES) { 737 if (ifmgd->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -755,7 +757,14 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
755 printk(KERN_DEBUG "%s: authenticate with AP %pM\n", 757 printk(KERN_DEBUG "%s: authenticate with AP %pM\n",
756 sdata->dev->name, ifmgd->bssid); 758 sdata->dev->name, ifmgd->bssid);
757 759
758 ieee80211_send_auth(sdata, 1, ifmgd->auth_alg, NULL, 0, 760 if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
761 ies = ifmgd->sme_auth_ie;
762 ies_len = ifmgd->sme_auth_ie_len;
763 } else {
764 ies = NULL;
765 ies_len = 0;
766 }
767 ieee80211_send_auth(sdata, 1, ifmgd->auth_alg, ies, ies_len,
759 ifmgd->bssid, 0); 768 ifmgd->bssid, 0);
760 ifmgd->auth_transaction = 2; 769 ifmgd->auth_transaction = 2;
761 770
@@ -870,7 +879,8 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata)
870 int wep_privacy; 879 int wep_privacy;
871 int privacy_invoked; 880 int privacy_invoked;
872 881
873 if (!ifmgd || (ifmgd->flags & IEEE80211_STA_MIXED_CELL)) 882 if (!ifmgd || (ifmgd->flags & (IEEE80211_STA_MIXED_CELL |
883 IEEE80211_STA_EXT_SME)))
874 return 0; 884 return 0;
875 885
876 bss = ieee80211_rx_bss_get(local, ifmgd->bssid, 886 bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
@@ -998,7 +1008,11 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata)
998 1008
999 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name); 1009 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
1000 ifmgd->flags |= IEEE80211_STA_AUTHENTICATED; 1010 ifmgd->flags |= IEEE80211_STA_AUTHENTICATED;
1001 ieee80211_associate(sdata); 1011 if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
1012 /* Wait for SME to request association */
1013 ifmgd->state = IEEE80211_STA_MLME_DISABLED;
1014 } else
1015 ieee80211_associate(sdata);
1002} 1016}
1003 1017
1004 1018
@@ -1084,6 +1098,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1084 switch (ifmgd->auth_alg) { 1098 switch (ifmgd->auth_alg) {
1085 case WLAN_AUTH_OPEN: 1099 case WLAN_AUTH_OPEN:
1086 case WLAN_AUTH_LEAP: 1100 case WLAN_AUTH_LEAP:
1101 case WLAN_AUTH_FT:
1087 ieee80211_auth_completed(sdata); 1102 ieee80211_auth_completed(sdata);
1088 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len); 1103 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len);
1089 break; 1104 break;
@@ -1117,9 +1132,10 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1117 printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n", 1132 printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n",
1118 sdata->dev->name, reason_code); 1133 sdata->dev->name, reason_code);
1119 1134
1120 if (ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE || 1135 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
1121 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE || 1136 (ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE ||
1122 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) { 1137 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE ||
1138 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)) {
1123 ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE; 1139 ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1124 mod_timer(&ifmgd->timer, jiffies + 1140 mod_timer(&ifmgd->timer, jiffies +
1125 IEEE80211_RETRY_AUTH_INTERVAL); 1141 IEEE80211_RETRY_AUTH_INTERVAL);
@@ -1150,7 +1166,8 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1150 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", 1166 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
1151 sdata->dev->name, reason_code); 1167 sdata->dev->name, reason_code);
1152 1168
1153 if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) { 1169 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
1170 ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) {
1154 ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE; 1171 ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE;
1155 mod_timer(&ifmgd->timer, jiffies + 1172 mod_timer(&ifmgd->timer, jiffies +
1156 IEEE80211_RETRY_AUTH_INTERVAL); 1173 IEEE80211_RETRY_AUTH_INTERVAL);
@@ -1664,6 +1681,8 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata)
1664 ifmgd->auth_alg = WLAN_AUTH_SHARED_KEY; 1681 ifmgd->auth_alg = WLAN_AUTH_SHARED_KEY;
1665 else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_LEAP) 1682 else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_LEAP)
1666 ifmgd->auth_alg = WLAN_AUTH_LEAP; 1683 ifmgd->auth_alg = WLAN_AUTH_LEAP;
1684 else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_FT)
1685 ifmgd->auth_alg = WLAN_AUTH_FT;
1667 else 1686 else
1668 ifmgd->auth_alg = WLAN_AUTH_OPEN; 1687 ifmgd->auth_alg = WLAN_AUTH_OPEN;
1669 ifmgd->auth_transaction = -1; 1688 ifmgd->auth_transaction = -1;
@@ -1687,7 +1706,8 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
1687 u16 capa_val = WLAN_CAPABILITY_ESS; 1706 u16 capa_val = WLAN_CAPABILITY_ESS;
1688 struct ieee80211_channel *chan = local->oper_channel; 1707 struct ieee80211_channel *chan = local->oper_channel;
1689 1708
1690 if (ifmgd->flags & (IEEE80211_STA_AUTO_SSID_SEL | 1709 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
1710 ifmgd->flags & (IEEE80211_STA_AUTO_SSID_SEL |
1691 IEEE80211_STA_AUTO_BSSID_SEL | 1711 IEEE80211_STA_AUTO_BSSID_SEL |
1692 IEEE80211_STA_AUTO_CHANNEL_SEL)) { 1712 IEEE80211_STA_AUTO_CHANNEL_SEL)) {
1693 capa_mask |= WLAN_CAPABILITY_PRIVACY; 1713 capa_mask |= WLAN_CAPABILITY_PRIVACY;
@@ -1884,7 +1904,11 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata)
1884 ieee80211_set_disassoc(sdata, true, true, 1904 ieee80211_set_disassoc(sdata, true, true,
1885 WLAN_REASON_DEAUTH_LEAVING); 1905 WLAN_REASON_DEAUTH_LEAVING);
1886 1906
1887 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); 1907 if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) ||
1908 ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE)
1909 set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
1910 else if (ifmgd->flags & IEEE80211_STA_EXT_SME)
1911 set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
1888 queue_work(local->hw.workqueue, &ifmgd->work); 1912 queue_work(local->hw.workqueue, &ifmgd->work);
1889 } 1913 }
1890} 1914}
@@ -1953,7 +1977,8 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
1953 return ieee80211_sta_commit(sdata); 1977 return ieee80211_sta_commit(sdata);
1954} 1978}
1955 1979
1956int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len) 1980int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
1981 const char *ie, size_t len)
1957{ 1982{
1958 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1983 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1959 1984