summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-05-06 22:09:37 +0300
committerJohn W. Linville <linville@tuxdriver.com>2009-05-11 15:23:54 -0400
commitdc6382ced07d6bad61d0b591fb12ab5da7ca632c (patch)
tree277d03c28c0756368d663d1b053ceaed196f666e
parented9b58bc443a1210b5be1ded6421b17e015bf985 (diff)
nl80211 : Add support for configuring MFP
NL80211_CMD_ASSOCIATE request must be able to indicate whether management frame protection (IEEE 802.11w) is being used. mac80211 was able to use MFP in client mode only with WEXT, but the new NL80211_ATTR_USE_MFP attribute will allow this to be done with nl80211, too. Since we are currently using nl80211 for MFP only with drivers that use user space SME, only MFP disabled and required values are used. However, the NL80211_ATTR_USE_MFP attribute is an enum that can be extended with MFP optional in the future, if that is needed with some drivers (e.g., if the RSN IE is generated by the driver). Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/linux/nl80211.h17
-rw-r--r--include/net/cfg80211.h2
-rw-r--r--net/mac80211/cfg.c8
-rw-r--r--net/wireless/nl80211.c12
4 files changed, 39 insertions, 0 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index e9fd13aa79f0..58c4ee1822d3 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -494,6 +494,11 @@ enum nl80211_commands {
* @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
* is used, e.g., with %NL80211_CMD_AUTHENTICATE event
*
+ * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
+ * used for the association (&enum nl80211_mfp, represented as a u32);
+ * this attribute can be used
+ * with %NL80211_CMD_ASSOCIATE request
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -596,6 +601,8 @@ enum nl80211_attrs {
NL80211_ATTR_TIMED_OUT,
+ NL80211_ATTR_USE_MFP,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1179,4 +1186,14 @@ enum nl80211_key_type {
NL80211_KEYTYPE_PEERKEY,
};
+/**
+ * enum nl80211_mfp - Management frame protection state
+ * @NL80211_MFP_NO: Management frame protection not used
+ * @NL80211_MFP_REQUIRED: Management frame protection required
+ */
+enum nl80211_mfp {
+ NL80211_MFP_NO,
+ NL80211_MFP_REQUIRED,
+};
+
#endif /* __LINUX_NL80211_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b8a76764e1c5..47e30e1d91fe 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -672,6 +672,7 @@ struct cfg80211_auth_request {
* @ssid_len: Length of ssid in octets
* @ie: Extra IEs to add to (Re)Association Request frame or %NULL
* @ie_len: Length of ie buffer in octets
+ * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
*/
struct cfg80211_assoc_request {
struct ieee80211_channel *chan;
@@ -680,6 +681,7 @@ struct cfg80211_assoc_request {
size_t ssid_len;
const u8 *ie;
size_t ie_len;
+ bool use_mfp;
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d0ca6da33ca9..4e627cf2b8c1 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1253,6 +1253,14 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
if (ret)
return ret;
+ if (req->use_mfp) {
+ sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
+ sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
+ } else {
+ sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
+ }
+
sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
ieee80211_sta_req_auth(sdata);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3c53c5cbc3a9..79927706937a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -122,6 +122,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
[NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
[NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
[NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
+ [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
};
/* IE validation */
@@ -3012,6 +3013,17 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
+ if (info->attrs[NL80211_ATTR_USE_MFP]) {
+ enum nl80211_mfp use_mfp =
+ nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
+ if (use_mfp == NL80211_MFP_REQUIRED)
+ req.use_mfp = true;
+ else if (use_mfp != NL80211_MFP_NO) {
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
err = drv->ops->assoc(&drv->wiphy, dev, &req);
out: