summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-02-26 17:57:29 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2019-02-26 17:57:28 -0800
commitd635dfb3abec27871faaf1cbbfd07ee39fe5ca40 (patch)
tree0e834bd68983e655c0ed9ddea2e9a0d492b35ce9
parent93f561a9ef96f8c96778656cf25dbd8b5473f03d (diff)
parentd317e07937f2332cd38fdb14308114e3e538ebce (diff)
Merge "cfg80211: Authentication offload to user space in AP mode"
-rw-r--r--include/net/cfg80211.h15
-rw-r--r--include/uapi/linux/nl80211.h13
-rw-r--r--net/wireless/nl80211.c25
3 files changed, 42 insertions, 11 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bac128ded4f0..03b4d4479ce4 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -728,6 +728,17 @@ struct cfg80211_bitrate_mask {
};
/**
+ * 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
*
* Used to configure an AP interface.
@@ -752,6 +763,7 @@ struct cfg80211_bitrate_mask {
* @pbss: If set, start as a PCP instead of AP. Relevant for DMG
* networks.
* @beacon_rate: bitrate to be used for beacons
+ * @flags: flags, as defined in enum cfg80211_ap_settings_flags
*/
struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
@@ -772,6 +784,7 @@ struct cfg80211_ap_settings {
const struct cfg80211_acl_data *acl;
bool pbss;
struct cfg80211_bitrate_mask beacon_rate;
+ u32 flags;
};
/**
@@ -2416,6 +2429,7 @@ struct cfg80211_qos_map {
* use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
* the real status code for failures. Used only for the authentication
* response command interface (user space to driver).
+ * @pmkid: The identifier to refer a PMKSA.
*/
struct cfg80211_external_auth_params {
enum nl80211_external_auth_action action;
@@ -2423,6 +2437,7 @@ struct cfg80211_external_auth_params {
struct cfg80211_ssid ssid;
unsigned int key_mgmt_suite;
u16 status;
+ const u8 *pmkid;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index a9fec3ba2aeb..5ad28e4fe7d6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2101,10 +2101,10 @@ enum nl80211_commands {
* &enum nl80211_external_auth_action value). This is used with the
* &NL80211_CMD_EXTERNAL_AUTH request event.
* @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
- * space supports external authentication. This attribute shall be used
- * only with %NL80211_CMD_CONNECT request. The driver may offload
- * authentication processing to user space if this capability is indicated
- * in NL80211_CMD_CONNECT requests from the user space.
+ * space supports external authentication. This attribute shall be used
+ * with %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP request. The driver
+ * may offload authentication processing to user space if this capability
+ * is indicated in the respective requests from the user space.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -5057,9 +5057,14 @@ enum nl80211_crit_proto_id {
* Used by cfg80211_rx_mgmt()
*
* @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 {
NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
+ NL80211_RXMGMT_FLAG_EXTERNAL_AUTH = 1 << 1,
};
/*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b2d90f48227d..563b400b5301 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3877,6 +3877,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
return PTR_ERR(params.acl);
}
+ if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
+ params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
+
wdev_lock(wdev);
err = rdev_start_ap(rdev, dev, &params);
if (!err) {
@@ -11176,7 +11179,9 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
if (!rdev->ops->external_auth)
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;
if (!info->attrs[NL80211_ATTR_BSSID])
@@ -11187,18 +11192,24 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
memset(&params, 0, sizeof(params));
- params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
- if (params.ssid.ssid_len == 0 ||
- params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
- return -EINVAL;
- memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
- params.ssid.ssid_len);
+ if (info->attrs[NL80211_ATTR_SSID]) {
+ params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+ if (params.ssid.ssid_len == 0 ||
+ params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
+ return -EINVAL;
+ 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]),
ETH_ALEN);
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);
}