aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 {
494 * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this 494 * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
495 * is used, e.g., with %NL80211_CMD_AUTHENTICATE event 495 * is used, e.g., with %NL80211_CMD_AUTHENTICATE event
496 * 496 *
497 * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
498 * used for the association (&enum nl80211_mfp, represented as a u32);
499 * this attribute can be used
500 * with %NL80211_CMD_ASSOCIATE request
501 *
497 * @NL80211_ATTR_MAX: highest attribute number currently defined 502 * @NL80211_ATTR_MAX: highest attribute number currently defined
498 * @__NL80211_ATTR_AFTER_LAST: internal use 503 * @__NL80211_ATTR_AFTER_LAST: internal use
499 */ 504 */
@@ -596,6 +601,8 @@ enum nl80211_attrs {
596 601
597 NL80211_ATTR_TIMED_OUT, 602 NL80211_ATTR_TIMED_OUT,
598 603
604 NL80211_ATTR_USE_MFP,
605
599 /* add attributes here, update the policy in nl80211.c */ 606 /* add attributes here, update the policy in nl80211.c */
600 607
601 __NL80211_ATTR_AFTER_LAST, 608 __NL80211_ATTR_AFTER_LAST,
@@ -1179,4 +1186,14 @@ enum nl80211_key_type {
1179 NL80211_KEYTYPE_PEERKEY, 1186 NL80211_KEYTYPE_PEERKEY,
1180}; 1187};
1181 1188
1189/**
1190 * enum nl80211_mfp - Management frame protection state
1191 * @NL80211_MFP_NO: Management frame protection not used
1192 * @NL80211_MFP_REQUIRED: Management frame protection required
1193 */
1194enum nl80211_mfp {
1195 NL80211_MFP_NO,
1196 NL80211_MFP_REQUIRED,
1197};
1198
1182#endif /* __LINUX_NL80211_H */ 1199#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 {
672 * @ssid_len: Length of ssid in octets 672 * @ssid_len: Length of ssid in octets
673 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL 673 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
674 * @ie_len: Length of ie buffer in octets 674 * @ie_len: Length of ie buffer in octets
675 * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
675 */ 676 */
676struct cfg80211_assoc_request { 677struct cfg80211_assoc_request {
677 struct ieee80211_channel *chan; 678 struct ieee80211_channel *chan;
@@ -680,6 +681,7 @@ struct cfg80211_assoc_request {
680 size_t ssid_len; 681 size_t ssid_len;
681 const u8 *ie; 682 const u8 *ie;
682 size_t ie_len; 683 size_t ie_len;
684 bool use_mfp;
683}; 685};
684 686
685/** 687/**
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,
1253 if (ret) 1253 if (ret)
1254 return ret; 1254 return ret;
1255 1255
1256 if (req->use_mfp) {
1257 sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
1258 sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
1259 } else {
1260 sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
1261 sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
1262 }
1263
1256 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME; 1264 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
1257 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE; 1265 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
1258 ieee80211_sta_req_auth(sdata); 1266 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 = {
122 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, 122 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
123 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, 123 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
124 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG }, 124 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
125 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
125}; 126};
126 127
127/* IE validation */ 128/* IE validation */
@@ -3012,6 +3013,17 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3012 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3013 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3013 } 3014 }
3014 3015
3016 if (info->attrs[NL80211_ATTR_USE_MFP]) {
3017 enum nl80211_mfp use_mfp =
3018 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
3019 if (use_mfp == NL80211_MFP_REQUIRED)
3020 req.use_mfp = true;
3021 else if (use_mfp != NL80211_MFP_NO) {
3022 err = -EINVAL;
3023 goto out;
3024 }
3025 }
3026
3015 err = drv->ops->assoc(&drv->wiphy, dev, &req); 3027 err = drv->ops->assoc(&drv->wiphy, dev, &req);
3016 3028
3017out: 3029out: