diff options
-rw-r--r-- | include/linux/nl80211.h | 17 | ||||
-rw-r--r-- | include/net/cfg80211.h | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 8 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 12 |
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 | */ | ||
1194 | enum 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 | */ |
676 | struct cfg80211_assoc_request { | 677 | struct 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 | ||
3017 | out: | 3029 | out: |