Commit fe494370 authored by Srinivas Dasari's avatar Srinivas Dasari Committed by Johannes Berg

cfg80211: Authentication offload to user space in AP mode

commit 40cbfa90 ("cfg80211/nl80211: Optional authentication
offload to userspace")' introduced authentication offload to user
space by the host drivers in station mode. This commit extends
the same for the AP mode too.

Extend NL80211_ATTR_EXTERNAL_AUTH_SUPPORT to also claim the
support of external authentication from the user space in AP mode.
A new flag parameter is introduced in cfg80211_ap_settings to
intend the same while "start ap".

Host driver to use NL80211_CMD_FRAME interface to transmit and
receive the authentication frames to / from the user space.

Host driver to indicate the flag NL80211_RXMGMT_FLAG_EXTERNAL_AUTH
while sending the authentication frame to the user space. This
intends to the user space that the driver wishes it to process
the authentication frame for certain protocols, though it had
initially advertised the support for SME functionality.

User space shall accordingly do the authentication and indicate
its final status through the command NL80211_CMD_EXTERNAL_AUTH.
Allow the command even if userspace doesn't include the attribute
NL80211_ATTR_SSID for AP interface.

Host driver shall continue with the association sequence and
indicate the STA connection status through cfg80211_new_sta.

To facilitate the host drivers in AP mode for matching the pmkid
by the stations during the association, NL80211_CMD_EXTERNAL_AUTH
is also enhanced to include the pmkid to drivers after
the authentication.
This pmkid can also be used in the STA mode to include in the
association request.

Also modify nl80211_external_auth to not mandate SSID in AP mode.
Signed-off-by: default avatarSrinivas Dasari <dasaris@codeaurora.org>
[remove useless nla_get_flag() usage]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent ab4dfa20
...@@ -835,6 +835,17 @@ struct cfg80211_bitrate_mask { ...@@ -835,6 +835,17 @@ struct cfg80211_bitrate_mask {
} control[NUM_NL80211_BANDS]; } control[NUM_NL80211_BANDS];
}; };
/**
* enum cfg80211_ap_settings_flags - AP settings flags
*
* Used by cfg80211_ap_settings
*
* @AP_SETTINGS_EXTERNAL_AUTH_SUPPORT: AP supports external authentication
*/
enum cfg80211_ap_settings_flags {
AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = BIT(0),
};
/** /**
* struct cfg80211_ap_settings - AP configuration * struct cfg80211_ap_settings - AP configuration
* *
...@@ -865,6 +876,7 @@ struct cfg80211_bitrate_mask { ...@@ -865,6 +876,7 @@ struct cfg80211_bitrate_mask {
* @he_cap: HE capabilities (or %NULL if HE isn't enabled) * @he_cap: HE capabilities (or %NULL if HE isn't enabled)
* @ht_required: stations must support HT * @ht_required: stations must support HT
* @vht_required: stations must support VHT * @vht_required: stations must support VHT
* @flags: flags, as defined in enum cfg80211_ap_settings_flags
*/ */
struct cfg80211_ap_settings { struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef; struct cfg80211_chan_def chandef;
...@@ -890,6 +902,7 @@ struct cfg80211_ap_settings { ...@@ -890,6 +902,7 @@ struct cfg80211_ap_settings {
const struct ieee80211_vht_cap *vht_cap; const struct ieee80211_vht_cap *vht_cap;
const struct ieee80211_he_cap_elem *he_cap; const struct ieee80211_he_cap_elem *he_cap;
bool ht_required, vht_required; bool ht_required, vht_required;
u32 flags;
}; };
/** /**
...@@ -2831,6 +2844,7 @@ struct cfg80211_pmk_conf { ...@@ -2831,6 +2844,7 @@ struct cfg80211_pmk_conf {
* use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you * use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
* the real status code for failures. Used only for the authentication * the real status code for failures. Used only for the authentication
* response command interface (user space to driver). * response command interface (user space to driver).
* @pmkid: The identifier to refer a PMKSA.
*/ */
struct cfg80211_external_auth_params { struct cfg80211_external_auth_params {
enum nl80211_external_auth_action action; enum nl80211_external_auth_action action;
...@@ -2838,6 +2852,7 @@ struct cfg80211_external_auth_params { ...@@ -2838,6 +2852,7 @@ struct cfg80211_external_auth_params {
struct cfg80211_ssid ssid; struct cfg80211_ssid ssid;
unsigned int key_mgmt_suite; unsigned int key_mgmt_suite;
u16 status; u16 status;
const u8 *pmkid;
}; };
/** /**
......
...@@ -2266,10 +2266,10 @@ enum nl80211_commands { ...@@ -2266,10 +2266,10 @@ enum nl80211_commands {
* &enum nl80211_external_auth_action value). This is used with the * &enum nl80211_external_auth_action value). This is used with the
* %NL80211_CMD_EXTERNAL_AUTH request event. * %NL80211_CMD_EXTERNAL_AUTH request event.
* @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
* space supports external authentication. This attribute shall be used * space supports external authentication. This attribute shall be used
* only with %NL80211_CMD_CONNECT request. The driver may offload * with %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP request. The driver
* authentication processing to user space if this capability is indicated * may offload authentication processing to user space if this capability
* in NL80211_CMD_CONNECT requests from the user space. * is indicated in the respective requests from the user space.
* *
* @NL80211_ATTR_NSS: Station's New/updated RX_NSS value notified using this * @NL80211_ATTR_NSS: Station's New/updated RX_NSS value notified using this
* u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED. * u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED.
...@@ -5631,9 +5631,14 @@ enum nl80211_crit_proto_id { ...@@ -5631,9 +5631,14 @@ enum nl80211_crit_proto_id {
* Used by cfg80211_rx_mgmt() * Used by cfg80211_rx_mgmt()
* *
* @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver. * @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver.
* @NL80211_RXMGMT_FLAG_EXTERNAL_AUTH: Host driver intends to offload
* the authentication. Exclusively defined for host drivers that
* advertises the SME functionality but would like the userspace
* to handle certain authentication algorithms (e.g. SAE).
*/ */
enum nl80211_rxmgmt_flags { enum nl80211_rxmgmt_flags {
NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0, NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
NL80211_RXMGMT_FLAG_EXTERNAL_AUTH = 1 << 1,
}; };
/* /*
......
...@@ -4550,6 +4550,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) ...@@ -4550,6 +4550,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
nl80211_calculate_ap_params(&params); nl80211_calculate_ap_params(&params);
if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
wdev_lock(wdev); wdev_lock(wdev);
err = rdev_start_ap(rdev, dev, &params); err = rdev_start_ap(rdev, dev, &params);
if (!err) { if (!err) {
...@@ -13086,7 +13089,9 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info) ...@@ -13086,7 +13089,9 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->external_auth) if (!rdev->ops->external_auth)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (!info->attrs[NL80211_ATTR_SSID]) if (!info->attrs[NL80211_ATTR_SSID] &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EINVAL; return -EINVAL;
if (!info->attrs[NL80211_ATTR_BSSID]) if (!info->attrs[NL80211_ATTR_BSSID])
...@@ -13097,18 +13102,24 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info) ...@@ -13097,18 +13102,24 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); if (info->attrs[NL80211_ATTR_SSID]) {
if (params.ssid.ssid_len == 0 || params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN) if (params.ssid.ssid_len == 0 ||
return -EINVAL; params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]), return -EINVAL;
params.ssid.ssid_len); memcpy(params.ssid.ssid,
nla_data(info->attrs[NL80211_ATTR_SSID]),
params.ssid.ssid_len);
}
memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]), memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
ETH_ALEN); ETH_ALEN);
params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
if (info->attrs[NL80211_ATTR_PMKID])
params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
return rdev_external_auth(rdev, dev, &params); return rdev_external_auth(rdev, dev, &params);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment