Commit 9946ecfb authored by Jouni Malinen's avatar Jouni Malinen Committed by John W. Linville

nl80211/cfg80211: Add extra IE configuration to AP mode setup

The NL80211_CMD_NEW_BEACON command is, in practice, requesting AP mode
operations to be started. Add new attributes to provide extra IEs
(e.g., WPS IE, P2P IE) for drivers that build Beacon, Probe Response,
and (Re)Association Response frames internally (likely in firmware).
Signed-off-by: default avatarJouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5fb628e9
...@@ -166,7 +166,8 @@ ...@@ -166,7 +166,8 @@
* %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
* %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
* %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
* %NL80211_ATTR_AUTH_TYPE. * %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_IE, %NL80211_ATTR_IE_PROBE_RESP,
* %NL80211_ATTR_IE_ASSOC_RESP.
* @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface, * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface,
* parameters are like for %NL80211_CMD_SET_BEACON. * parameters are like for %NL80211_CMD_SET_BEACON.
* @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
...@@ -1031,6 +1032,16 @@ enum nl80211_commands { ...@@ -1031,6 +1032,16 @@ enum nl80211_commands {
* and Probe Response (when response to wildcard Probe Request); see * and Probe Response (when response to wildcard Probe Request); see
* &enum nl80211_hidden_ssid, represented as a u32 * &enum nl80211_hidden_ssid, represented as a u32
* *
* @NL80211_ATTR_IE_PROBE_RESP: Information element(s) for Probe Response frame.
* This is used with %NL80211_CMD_NEW_BEACON and %NL80211_CMD_SET_BEACON to
* provide extra IEs (e.g., WPS/P2P IE) into Probe Response frames when the
* driver (or firmware) replies to Probe Request frames.
* @NL80211_ATTR_IE_ASSOC_RESP: Information element(s) for (Re)Association
* Response frames. This is used with %NL80211_CMD_NEW_BEACON and
* %NL80211_CMD_SET_BEACON to provide extra IEs (e.g., WPS/P2P IE) into
* (Re)Association Response frames when the driver (or firmware) replies to
* (Re)Association Request frames.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined * @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use * @__NL80211_ATTR_AFTER_LAST: internal use
*/ */
...@@ -1238,6 +1249,9 @@ enum nl80211_attrs { ...@@ -1238,6 +1249,9 @@ enum nl80211_attrs {
NL80211_ATTR_HIDDEN_SSID, NL80211_ATTR_HIDDEN_SSID,
NL80211_ATTR_IE_PROBE_RESP,
NL80211_ATTR_IE_ASSOC_RESP,
/* add attributes here, update the policy in nl80211.c */ /* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST, __NL80211_ATTR_AFTER_LAST,
......
...@@ -383,6 +383,14 @@ struct cfg80211_crypto_settings { ...@@ -383,6 +383,14 @@ struct cfg80211_crypto_settings {
* @crypto: crypto settings * @crypto: crypto settings
* @privacy: the BSS uses privacy * @privacy: the BSS uses privacy
* @auth_type: Authentication type (algorithm) * @auth_type: Authentication type (algorithm)
* @beacon_ies: extra information element(s) to add into Beacon frames or %NULL
* @beacon_ies_len: length of beacon_ies in octets
* @proberesp_ies: extra information element(s) to add into Probe Response
* frames or %NULL
* @proberesp_ies_len: length of proberesp_ies in octets
* @assocresp_ies: extra information element(s) to add into (Re)Association
* Response frames or %NULL
* @assocresp_ies_len: length of assocresp_ies in octets
*/ */
struct beacon_parameters { struct beacon_parameters {
u8 *head, *tail; u8 *head, *tail;
...@@ -394,6 +402,12 @@ struct beacon_parameters { ...@@ -394,6 +402,12 @@ struct beacon_parameters {
struct cfg80211_crypto_settings crypto; struct cfg80211_crypto_settings crypto;
bool privacy; bool privacy;
enum nl80211_auth_type auth_type; enum nl80211_auth_type auth_type;
const u8 *beacon_ies;
size_t beacon_ies_len;
const u8 *proberesp_ies;
size_t proberesp_ies_len;
const u8 *assocresp_ies;
size_t assocresp_ies_len;
}; };
/** /**
......
...@@ -185,6 +185,10 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { ...@@ -185,6 +185,10 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
[NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
[NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 }, [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
[NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
}; };
/* policy for the key attributes */ /* policy for the key attributes */
...@@ -1991,7 +1995,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) ...@@ -1991,7 +1995,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
struct beacon_parameters params; struct beacon_parameters params;
int haveinfo = 0, err; int haveinfo = 0, err;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) ||
!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) ||
!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]))
return -EINVAL; return -EINVAL;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
...@@ -2090,6 +2097,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) ...@@ -2090,6 +2097,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
if (!haveinfo) if (!haveinfo)
return -EINVAL; return -EINVAL;
if (info->attrs[NL80211_ATTR_IE]) {
params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) {
params.proberesp_ies =
nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
params.proberesp_ies_len =
nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
}
if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
params.assocresp_ies =
nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
params.assocresp_ies_len =
nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
}
err = call(&rdev->wiphy, dev, &params); err = call(&rdev->wiphy, dev, &params);
if (!err && params.interval) if (!err && params.interval)
wdev->beacon_interval = params.interval; wdev->beacon_interval = params.interval;
......
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