summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@codeaurora.org>2019-02-14 19:14:33 -0500
committerJohannes Berg <johannes.berg@intel.com>2019-02-22 07:35:09 -0500
commit4d9ec73d2b78daf70477aadc50eb4d2186c8b62f (patch)
treed551f1a96cfcfa40b2604980098c8cce0ae8c6e3
parent767637416e218d2d3ba7e1697b8a72a375797866 (diff)
cfg80211: Report Association Request frame IEs in association events
This extends the NL80211_CMD_ASSOCIATE event case to report NL80211_ATTR_REQ_IE similarly to what is already done with the NL80211_CMD_CONNECT events if the driver provides this information. In practice, this adds (Re)Association Request frame information element reporting to mac80211 drivers for the cases where user space SME is used. This provides more information for user space to figure out which capabilities were negotiated for the association. For example, this can be used to determine whether HT, VHT, or HE is used. Signed-off-by: Jouni Malinen <jouni@codeaurora.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h7
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/mlme.c14
-rw-r--r--net/wireless/mlme.c8
-rw-r--r--net/wireless/nl80211.c24
-rw-r--r--net/wireless/nl80211.h3
6 files changed, 46 insertions, 16 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f81677f2f051..7a29b709077f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5676,10 +5676,12 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr);
5676 * @dev: network device 5676 * @dev: network device
5677 * @bss: the BSS that association was requested with, ownership of the pointer 5677 * @bss: the BSS that association was requested with, ownership of the pointer
5678 * moves to cfg80211 in this call 5678 * moves to cfg80211 in this call
5679 * @buf: authentication frame (header + body) 5679 * @buf: (Re)Association Response frame (header + body)
5680 * @len: length of the frame data 5680 * @len: length of the frame data
5681 * @uapsd_queues: bitmap of queues configured for uapsd. Same format 5681 * @uapsd_queues: bitmap of queues configured for uapsd. Same format
5682 * as the AC bitmap in the QoS info field 5682 * as the AC bitmap in the QoS info field
5683 * @req_ies: information elements from the (Re)Association Request frame
5684 * @req_ies_len: length of req_ies data
5683 * 5685 *
5684 * After being asked to associate via cfg80211_ops::assoc() the driver must 5686 * After being asked to associate via cfg80211_ops::assoc() the driver must
5685 * call either this function or cfg80211_auth_timeout(). 5687 * call either this function or cfg80211_auth_timeout().
@@ -5689,7 +5691,8 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr);
5689void cfg80211_rx_assoc_resp(struct net_device *dev, 5691void cfg80211_rx_assoc_resp(struct net_device *dev,
5690 struct cfg80211_bss *bss, 5692 struct cfg80211_bss *bss,
5691 const u8 *buf, size_t len, 5693 const u8 *buf, size_t len,
5692 int uapsd_queues); 5694 int uapsd_queues,
5695 const u8 *req_ies, size_t req_ies_len);
5693 5696
5694/** 5697/**
5695 * cfg80211_assoc_timeout - notification of timed out association 5698 * cfg80211_assoc_timeout - notification of timed out association
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 5795eef98771..afce50da6fd6 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -556,6 +556,12 @@ struct ieee80211_if_managed {
556 * get stuck in a downgraded situation and flush takes forever. 556 * get stuck in a downgraded situation and flush takes forever.
557 */ 557 */
558 struct delayed_work tx_tspec_wk; 558 struct delayed_work tx_tspec_wk;
559
560 /* Information elements from the last transmitted (Re)Association
561 * Request frame.
562 */
563 u8 *assoc_req_ies;
564 size_t assoc_req_ies_len;
559}; 565};
560 566
561struct ieee80211_if_ibss { 567struct ieee80211_if_ibss {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a49fbb3f3ed7..df5d4b90616d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -644,7 +644,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
644 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; 644 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
645 struct sk_buff *skb; 645 struct sk_buff *skb;
646 struct ieee80211_mgmt *mgmt; 646 struct ieee80211_mgmt *mgmt;
647 u8 *pos, qos_info; 647 u8 *pos, qos_info, *ie_start;
648 size_t offset = 0, noffset; 648 size_t offset = 0, noffset;
649 int i, count, rates_len, supp_rates_len, shift; 649 int i, count, rates_len, supp_rates_len, shift;
650 u16 capab; 650 u16 capab;
@@ -752,6 +752,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
752 752
753 /* SSID */ 753 /* SSID */
754 pos = skb_put(skb, 2 + assoc_data->ssid_len); 754 pos = skb_put(skb, 2 + assoc_data->ssid_len);
755 ie_start = pos;
755 *pos++ = WLAN_EID_SSID; 756 *pos++ = WLAN_EID_SSID;
756 *pos++ = assoc_data->ssid_len; 757 *pos++ = assoc_data->ssid_len;
757 memcpy(pos, assoc_data->ssid, assoc_data->ssid_len); 758 memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);
@@ -976,6 +977,11 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
976 return; 977 return;
977 } 978 }
978 979
980 pos = skb_tail_pointer(skb);
981 kfree(ifmgd->assoc_req_ies);
982 ifmgd->assoc_req_ies = kmemdup(ie_start, pos - ie_start, GFP_ATOMIC);
983 ifmgd->assoc_req_ies_len = pos - ie_start;
984
979 drv_mgd_prepare_tx(local, sdata, 0); 985 drv_mgd_prepare_tx(local, sdata, 0);
980 986
981 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 987 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
@@ -3544,7 +3550,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
3544 uapsd_queues |= ieee80211_ac_to_qos_mask[ac]; 3550 uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
3545 } 3551 }
3546 3552
3547 cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len, uapsd_queues); 3553 cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len, uapsd_queues,
3554 ifmgd->assoc_req_ies, ifmgd->assoc_req_ies_len);
3548} 3555}
3549 3556
3550static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 3557static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -5576,6 +5583,9 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
5576 ifmgd->teardown_skb = NULL; 5583 ifmgd->teardown_skb = NULL;
5577 ifmgd->orig_teardown_skb = NULL; 5584 ifmgd->orig_teardown_skb = NULL;
5578 } 5585 }
5586 kfree(ifmgd->assoc_req_ies);
5587 ifmgd->assoc_req_ies = NULL;
5588 ifmgd->assoc_req_ies_len = 0;
5579 spin_unlock_bh(&ifmgd->teardown_lock); 5589 spin_unlock_bh(&ifmgd->teardown_lock);
5580 del_timer_sync(&ifmgd->timer); 5590 del_timer_sync(&ifmgd->timer);
5581 sdata_unlock(sdata); 5591 sdata_unlock(sdata);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 1615e503f8e3..f9462010575f 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -21,7 +21,8 @@
21 21
22 22
23void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, 23void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
24 const u8 *buf, size_t len, int uapsd_queues) 24 const u8 *buf, size_t len, int uapsd_queues,
25 const u8 *req_ies, size_t req_ies_len)
25{ 26{
26 struct wireless_dev *wdev = dev->ieee80211_ptr; 27 struct wireless_dev *wdev = dev->ieee80211_ptr;
27 struct wiphy *wiphy = wdev->wiphy; 28 struct wiphy *wiphy = wdev->wiphy;
@@ -33,6 +34,8 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
33 cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code); 34 cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code);
34 cr.bssid = mgmt->bssid; 35 cr.bssid = mgmt->bssid;
35 cr.bss = bss; 36 cr.bss = bss;
37 cr.req_ie = req_ies;
38 cr.req_ie_len = req_ies_len;
36 cr.resp_ie = mgmt->u.assoc_resp.variable; 39 cr.resp_ie = mgmt->u.assoc_resp.variable;
37 cr.resp_ie_len = 40 cr.resp_ie_len =
38 len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 41 len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
@@ -52,7 +55,8 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
52 return; 55 return;
53 } 56 }
54 57
55 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues); 58 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues,
59 req_ies, req_ies_len);
56 /* update current_bss etc., consumes the bss reference */ 60 /* update current_bss etc., consumes the bss reference */
57 __cfg80211_connect_result(dev, &cr, cr.status == WLAN_STATUS_SUCCESS); 61 __cfg80211_connect_result(dev, &cr, cr.status == WLAN_STATUS_SUCCESS);
58} 62}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 80878b431584..d5badbbb28a3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14491,12 +14491,13 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
14491 struct net_device *netdev, 14491 struct net_device *netdev,
14492 const u8 *buf, size_t len, 14492 const u8 *buf, size_t len,
14493 enum nl80211_commands cmd, gfp_t gfp, 14493 enum nl80211_commands cmd, gfp_t gfp,
14494 int uapsd_queues) 14494 int uapsd_queues, const u8 *req_ies,
14495 size_t req_ies_len)
14495{ 14496{
14496 struct sk_buff *msg; 14497 struct sk_buff *msg;
14497 void *hdr; 14498 void *hdr;
14498 14499
14499 msg = nlmsg_new(100 + len, gfp); 14500 msg = nlmsg_new(100 + len + req_ies_len, gfp);
14500 if (!msg) 14501 if (!msg)
14501 return; 14502 return;
14502 14503
@@ -14508,7 +14509,9 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
14508 14509
14509 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 14510 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14510 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || 14511 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14511 nla_put(msg, NL80211_ATTR_FRAME, len, buf)) 14512 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
14513 (req_ies &&
14514 nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
14512 goto nla_put_failure; 14515 goto nla_put_failure;
14513 14516
14514 if (uapsd_queues >= 0) { 14517 if (uapsd_queues >= 0) {
@@ -14539,15 +14542,17 @@ void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
14539 size_t len, gfp_t gfp) 14542 size_t len, gfp_t gfp)
14540{ 14543{
14541 nl80211_send_mlme_event(rdev, netdev, buf, len, 14544 nl80211_send_mlme_event(rdev, netdev, buf, len,
14542 NL80211_CMD_AUTHENTICATE, gfp, -1); 14545 NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0);
14543} 14546}
14544 14547
14545void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, 14548void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
14546 struct net_device *netdev, const u8 *buf, 14549 struct net_device *netdev, const u8 *buf,
14547 size_t len, gfp_t gfp, int uapsd_queues) 14550 size_t len, gfp_t gfp, int uapsd_queues,
14551 const u8 *req_ies, size_t req_ies_len)
14548{ 14552{
14549 nl80211_send_mlme_event(rdev, netdev, buf, len, 14553 nl80211_send_mlme_event(rdev, netdev, buf, len,
14550 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues); 14554 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
14555 req_ies, req_ies_len);
14551} 14556}
14552 14557
14553void nl80211_send_deauth(struct cfg80211_registered_device *rdev, 14558void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
@@ -14555,7 +14560,7 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
14555 size_t len, gfp_t gfp) 14560 size_t len, gfp_t gfp)
14556{ 14561{
14557 nl80211_send_mlme_event(rdev, netdev, buf, len, 14562 nl80211_send_mlme_event(rdev, netdev, buf, len,
14558 NL80211_CMD_DEAUTHENTICATE, gfp, -1); 14563 NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0);
14559} 14564}
14560 14565
14561void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, 14566void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
@@ -14563,7 +14568,7 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
14563 size_t len, gfp_t gfp) 14568 size_t len, gfp_t gfp)
14564{ 14569{
14565 nl80211_send_mlme_event(rdev, netdev, buf, len, 14570 nl80211_send_mlme_event(rdev, netdev, buf, len,
14566 NL80211_CMD_DISASSOCIATE, gfp, -1); 14571 NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0);
14567} 14572}
14568 14573
14569void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, 14574void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
@@ -14584,7 +14589,8 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
14584 cmd = NL80211_CMD_UNPROT_DISASSOCIATE; 14589 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
14585 14590
14586 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); 14591 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
14587 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1); 14592 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
14593 NULL, 0);
14588} 14594}
14589EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt); 14595EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
14590 14596
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 531c82dcba6b..a41e94a49a89 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -67,7 +67,8 @@ void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
67void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, 67void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
68 struct net_device *netdev, 68 struct net_device *netdev,
69 const u8 *buf, size_t len, gfp_t gfp, 69 const u8 *buf, size_t len, gfp_t gfp,
70 int uapsd_queues); 70 int uapsd_queues,
71 const u8 *req_ies, size_t req_ies_len);
71void nl80211_send_deauth(struct cfg80211_registered_device *rdev, 72void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
72 struct net_device *netdev, 73 struct net_device *netdev,
73 const u8 *buf, size_t len, gfp_t gfp); 74 const u8 *buf, size_t len, gfp_t gfp);