Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cfg80211/nl80211: Add PMKSA caching candidate event

When the driver (or most likely firmware) decides which AP to use
for roaming based on internal scan result processing, user space
needs to be notified of PMKSA caching candidates to allow RSN
pre-authentication to be used.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Jouni Malinen and committed by
John W. Linville
c9df56b4 29818082

+105
+33
include/linux/nl80211.h
··· 499 499 * this command may also be sent by the driver as an MLME event to 500 500 * inform userspace of the new replay counter. 501 501 * 502 + * @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace 503 + * of PMKSA caching dandidates. 504 + * 502 505 * @NL80211_CMD_MAX: highest used command number 503 506 * @__NL80211_CMD_AFTER_LAST: internal use 504 507 */ ··· 625 622 NL80211_CMD_SCHED_SCAN_STOPPED, 626 623 627 624 NL80211_CMD_SET_REKEY_OFFLOAD, 625 + 626 + NL80211_CMD_PMKSA_CANDIDATE, 628 627 629 628 /* add new commands above here */ 630 629 ··· 1075 1070 * @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of 1076 1071 * roaming to another AP in the same ESS if the signal lever is low. 1077 1072 * 1073 + * @NL80211_ATTR_PMKSA_CANDIDATE: Nested attribute containing the PMKSA caching 1074 + * candidate information, see &enum nl80211_pmksa_candidate_attr. 1075 + * 1078 1076 * @NL80211_ATTR_MAX: highest attribute number currently defined 1079 1077 * @__NL80211_ATTR_AFTER_LAST: internal use 1080 1078 */ ··· 1295 1287 1296 1288 NL80211_ATTR_SCHED_SCAN_MATCH, 1297 1289 NL80211_ATTR_MAX_MATCH_SETS, 1290 + 1291 + NL80211_ATTR_PMKSA_CANDIDATE, 1298 1292 1299 1293 /* add attributes here, update the policy in nl80211.c */ 1300 1294 ··· 2566 2556 /* keep last */ 2567 2557 __NL80211_STA_WME_AFTER_LAST, 2568 2558 NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1 2559 + }; 2560 + 2561 + /** 2562 + * enum nl80211_pmksa_candidate_attr - attributes for PMKSA caching candidates 2563 + * @__NL80211_PMKSA_CANDIDATE_INVALID: invalid number for nested attributes 2564 + * @NL80211_PMKSA_CANDIDATE_INDEX: candidate index (u32; the smaller, the higher 2565 + * priority) 2566 + * @NL80211_PMKSA_CANDIDATE_BSSID: candidate BSSID (6 octets) 2567 + * @NL80211_PMKSA_CANDIDATE_PREAUTH: RSN pre-authentication supported (flag) 2568 + * @NUM_NL80211_PMKSA_CANDIDATE: number of PMKSA caching candidate attributes 2569 + * (internal) 2570 + * @MAX_NL80211_PMKSA_CANDIDATE: highest PMKSA caching candidate attribute 2571 + * (internal) 2572 + */ 2573 + enum nl80211_pmksa_candidate_attr { 2574 + __NL80211_PMKSA_CANDIDATE_INVALID, 2575 + NL80211_PMKSA_CANDIDATE_INDEX, 2576 + NL80211_PMKSA_CANDIDATE_BSSID, 2577 + NL80211_PMKSA_CANDIDATE_PREAUTH, 2578 + 2579 + /* keep last */ 2580 + NUM_NL80211_PMKSA_CANDIDATE, 2581 + MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1 2569 2582 }; 2570 2583 2571 2584 #endif /* __LINUX_NL80211_H */
+11
include/net/cfg80211.h
··· 3136 3136 void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, 3137 3137 const u8 *replay_ctr, gfp_t gfp); 3138 3138 3139 + /** 3140 + * cfg80211_pmksa_candidate_notify - notify about PMKSA caching candidate 3141 + * @dev: network device 3142 + * @index: candidate index (the smaller the index, the higher the priority) 3143 + * @bssid: BSSID of AP 3144 + * @preauth: Whether AP advertises support for RSN pre-authentication 3145 + * @gfp: allocation flags 3146 + */ 3147 + void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, 3148 + const u8 *bssid, bool preauth, gfp_t gfp); 3149 + 3139 3150 /* Logging, debugging and troubleshooting/diagnostic helpers. */ 3140 3151 3141 3152 /* wiphy_printk helpers, similar to dev_printk */
+11
net/wireless/mlme.c
··· 1095 1095 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); 1096 1096 } 1097 1097 EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); 1098 + 1099 + void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, 1100 + const u8 *bssid, bool preauth, gfp_t gfp) 1101 + { 1102 + struct wireless_dev *wdev = dev->ieee80211_ptr; 1103 + struct wiphy *wiphy = wdev->wiphy; 1104 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 1105 + 1106 + nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); 1107 + } 1108 + EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
+46
net/wireless/nl80211.c
··· 7270 7270 nlmsg_free(msg); 7271 7271 } 7272 7272 7273 + void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, 7274 + struct net_device *netdev, int index, 7275 + const u8 *bssid, bool preauth, gfp_t gfp) 7276 + { 7277 + struct sk_buff *msg; 7278 + struct nlattr *attr; 7279 + void *hdr; 7280 + 7281 + msg = nlmsg_new(NLMSG_GOODSIZE, gfp); 7282 + if (!msg) 7283 + return; 7284 + 7285 + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE); 7286 + if (!hdr) { 7287 + nlmsg_free(msg); 7288 + return; 7289 + } 7290 + 7291 + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); 7292 + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); 7293 + 7294 + attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE); 7295 + if (!attr) 7296 + goto nla_put_failure; 7297 + 7298 + NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index); 7299 + NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid); 7300 + if (preauth) 7301 + NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH); 7302 + 7303 + nla_nest_end(msg, attr); 7304 + 7305 + if (genlmsg_end(msg, hdr) < 0) { 7306 + nlmsg_free(msg); 7307 + return; 7308 + } 7309 + 7310 + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 7311 + nl80211_mlme_mcgrp.id, gfp); 7312 + return; 7313 + 7314 + nla_put_failure: 7315 + genlmsg_cancel(msg, hdr); 7316 + nlmsg_free(msg); 7317 + } 7318 + 7273 7319 void 7274 7320 nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 7275 7321 struct net_device *netdev, const u8 *peer,
+4
net/wireless/nl80211.h
··· 113 113 struct net_device *netdev, const u8 *bssid, 114 114 const u8 *replay_ctr, gfp_t gfp); 115 115 116 + void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, 117 + struct net_device *netdev, int index, 118 + const u8 *bssid, bool preauth, gfp_t gfp); 119 + 116 120 #endif /* __NET_WIRELESS_NL80211_H */