1 // SPDX-License-Identifier: GPL-2.0
3 * SME code for cfg80211
4 * both driver SME event handling and the SME implementation
5 * (for nl80211's connect() and wext)
7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
8 * Copyright (C) 2009, 2020, 2022-2024 Intel Corporation. All rights reserved.
9 * Copyright 2017 Intel Deutschland GmbH
12 #include <linux/etherdevice.h>
13 #include <linux/if_arp.h>
14 #include <linux/slab.h>
15 #include <linux/workqueue.h>
16 #include <linux/wireless.h>
17 #include <linux/export.h>
18 #include <net/iw_handler.h>
19 #include <net/cfg80211.h>
20 #include <net/rtnetlink.h>
26 * Software SME in cfg80211, using auth/assoc/deauth calls to the
27 * driver. This is for implementing nl80211's connect/disconnect
28 * and wireless extensions (if configured.)
31 struct cfg80211_conn
{
32 struct cfg80211_connect_params params
;
33 /* these are sub-states of the _CONNECTING sme_state */
35 CFG80211_CONN_SCANNING
,
36 CFG80211_CONN_SCAN_AGAIN
,
37 CFG80211_CONN_AUTHENTICATE_NEXT
,
38 CFG80211_CONN_AUTHENTICATING
,
39 CFG80211_CONN_AUTH_FAILED_TIMEOUT
,
40 CFG80211_CONN_ASSOCIATE_NEXT
,
41 CFG80211_CONN_ASSOCIATING
,
42 CFG80211_CONN_ASSOC_FAILED
,
43 CFG80211_CONN_ASSOC_FAILED_TIMEOUT
,
45 CFG80211_CONN_ABANDON
,
46 CFG80211_CONN_CONNECTED
,
48 u8 bssid
[ETH_ALEN
], prev_bssid
[ETH_ALEN
];
51 bool auto_auth
, prev_bssid_valid
;
54 static void cfg80211_sme_free(struct wireless_dev
*wdev
)
59 kfree(wdev
->conn
->ie
);
64 static int cfg80211_conn_scan(struct wireless_dev
*wdev
)
66 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
67 struct cfg80211_scan_request
*request
;
70 lockdep_assert_wiphy(wdev
->wiphy
);
72 if (rdev
->scan_req
|| rdev
->scan_msg
)
75 if (wdev
->conn
->params
.channel
)
78 n_channels
= ieee80211_get_num_supported_channels(wdev
->wiphy
);
80 request
= kzalloc(sizeof(*request
) + sizeof(request
->ssids
[0]) +
81 sizeof(request
->channels
[0]) * n_channels
,
86 if (wdev
->conn
->params
.channel
) {
87 enum nl80211_band band
= wdev
->conn
->params
.channel
->band
;
88 struct ieee80211_supported_band
*sband
=
89 wdev
->wiphy
->bands
[band
];
95 request
->channels
[0] = wdev
->conn
->params
.channel
;
96 request
->rates
[band
] = (1 << sband
->n_bitrates
) - 1;
99 enum nl80211_band band
;
100 struct ieee80211_supported_band
*bands
;
101 struct ieee80211_channel
*channel
;
103 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
104 bands
= wdev
->wiphy
->bands
[band
];
107 for (j
= 0; j
< bands
->n_channels
; j
++) {
108 channel
= &bands
->channels
[j
];
109 if (channel
->flags
& IEEE80211_CHAN_DISABLED
)
111 request
->channels
[i
++] = channel
;
113 request
->rates
[band
] = (1 << bands
->n_bitrates
) - 1;
117 request
->n_channels
= n_channels
;
118 request
->ssids
= (void *)request
+
119 struct_size(request
, channels
, n_channels
);
120 request
->n_ssids
= 1;
122 memcpy(request
->ssids
[0].ssid
, wdev
->conn
->params
.ssid
,
123 wdev
->conn
->params
.ssid_len
);
124 request
->ssids
[0].ssid_len
= wdev
->conn
->params
.ssid_len
;
126 eth_broadcast_addr(request
->bssid
);
128 request
->wdev
= wdev
;
129 request
->wiphy
= &rdev
->wiphy
;
130 request
->scan_start
= jiffies
;
132 rdev
->scan_req
= request
;
134 err
= cfg80211_scan(rdev
);
136 wdev
->conn
->state
= CFG80211_CONN_SCANNING
;
137 nl80211_send_scan_start(rdev
, wdev
);
138 dev_hold(wdev
->netdev
);
140 rdev
->scan_req
= NULL
;
146 static int cfg80211_conn_do_work(struct wireless_dev
*wdev
,
147 enum nl80211_timeout_reason
*treason
)
149 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
150 struct cfg80211_connect_params
*params
;
151 struct cfg80211_auth_request auth_req
= {};
152 struct cfg80211_assoc_request req
= {};
155 lockdep_assert_wiphy(wdev
->wiphy
);
160 params
= &wdev
->conn
->params
;
162 switch (wdev
->conn
->state
) {
163 case CFG80211_CONN_SCANNING
:
164 /* didn't find it during scan ... */
166 case CFG80211_CONN_SCAN_AGAIN
:
167 return cfg80211_conn_scan(wdev
);
168 case CFG80211_CONN_AUTHENTICATE_NEXT
:
169 if (WARN_ON(!rdev
->ops
->auth
))
171 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATING
;
172 auth_req
.key
= params
->key
;
173 auth_req
.key_len
= params
->key_len
;
174 auth_req
.key_idx
= params
->key_idx
;
175 auth_req
.auth_type
= params
->auth_type
;
176 auth_req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, params
->channel
,
178 params
->ssid
, params
->ssid_len
,
179 IEEE80211_BSS_TYPE_ESS
,
180 IEEE80211_PRIVACY_ANY
);
181 auth_req
.link_id
= -1;
182 err
= cfg80211_mlme_auth(rdev
, wdev
->netdev
, &auth_req
);
183 cfg80211_put_bss(&rdev
->wiphy
, auth_req
.bss
);
185 case CFG80211_CONN_AUTH_FAILED_TIMEOUT
:
186 *treason
= NL80211_TIMEOUT_AUTH
;
188 case CFG80211_CONN_ASSOCIATE_NEXT
:
189 if (WARN_ON(!rdev
->ops
->assoc
))
191 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATING
;
192 if (wdev
->conn
->prev_bssid_valid
)
193 req
.prev_bssid
= wdev
->conn
->prev_bssid
;
195 req
.ie_len
= params
->ie_len
;
196 req
.use_mfp
= params
->mfp
!= NL80211_MFP_NO
;
197 req
.crypto
= params
->crypto
;
198 req
.flags
= params
->flags
;
199 req
.ht_capa
= params
->ht_capa
;
200 req
.ht_capa_mask
= params
->ht_capa_mask
;
201 req
.vht_capa
= params
->vht_capa
;
202 req
.vht_capa_mask
= params
->vht_capa_mask
;
205 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, params
->channel
,
207 params
->ssid
, params
->ssid_len
,
208 IEEE80211_BSS_TYPE_ESS
,
209 IEEE80211_PRIVACY_ANY
);
213 err
= cfg80211_mlme_assoc(rdev
, wdev
->netdev
,
215 cfg80211_put_bss(&rdev
->wiphy
, req
.bss
);
219 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
221 WLAN_REASON_DEAUTH_LEAVING
,
224 case CFG80211_CONN_ASSOC_FAILED_TIMEOUT
:
225 *treason
= NL80211_TIMEOUT_ASSOC
;
227 case CFG80211_CONN_ASSOC_FAILED
:
228 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
230 WLAN_REASON_DEAUTH_LEAVING
, false);
232 case CFG80211_CONN_DEAUTH
:
233 cfg80211_mlme_deauth(rdev
, wdev
->netdev
, params
->bssid
,
235 WLAN_REASON_DEAUTH_LEAVING
, false);
237 case CFG80211_CONN_ABANDON
:
238 /* free directly, disconnected event already sent */
239 cfg80211_sme_free(wdev
);
246 void cfg80211_conn_work(struct work_struct
*work
)
248 struct cfg80211_registered_device
*rdev
=
249 container_of(work
, struct cfg80211_registered_device
, conn_work
);
250 struct wireless_dev
*wdev
;
251 u8 bssid_buf
[ETH_ALEN
], *bssid
= NULL
;
252 enum nl80211_timeout_reason treason
;
254 wiphy_lock(&rdev
->wiphy
);
256 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
) {
260 if (!netif_running(wdev
->netdev
))
264 wdev
->conn
->state
== CFG80211_CONN_CONNECTED
)
267 if (wdev
->conn
->params
.bssid
) {
268 memcpy(bssid_buf
, wdev
->conn
->params
.bssid
, ETH_ALEN
);
271 treason
= NL80211_TIMEOUT_UNSPECIFIED
;
272 if (cfg80211_conn_do_work(wdev
, &treason
)) {
273 struct cfg80211_connect_resp_params cr
;
275 memset(&cr
, 0, sizeof(cr
));
277 cr
.links
[0].bssid
= bssid
;
278 cr
.timeout_reason
= treason
;
279 __cfg80211_connect_result(wdev
->netdev
, &cr
, false);
283 wiphy_unlock(&rdev
->wiphy
);
286 static void cfg80211_step_auth_next(struct cfg80211_conn
*conn
,
287 struct cfg80211_bss
*bss
)
289 memcpy(conn
->bssid
, bss
->bssid
, ETH_ALEN
);
290 conn
->params
.bssid
= conn
->bssid
;
291 conn
->params
.channel
= bss
->channel
;
292 conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
295 /* Returned bss is reference counted and must be cleaned up appropriately. */
296 static struct cfg80211_bss
*cfg80211_get_conn_bss(struct wireless_dev
*wdev
)
298 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
299 struct cfg80211_bss
*bss
;
301 lockdep_assert_wiphy(wdev
->wiphy
);
303 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
304 wdev
->conn
->params
.bssid
,
305 wdev
->conn
->params
.ssid
,
306 wdev
->conn
->params
.ssid_len
,
308 IEEE80211_PRIVACY(wdev
->conn
->params
.privacy
));
312 cfg80211_step_auth_next(wdev
->conn
, bss
);
313 schedule_work(&rdev
->conn_work
);
318 void cfg80211_sme_scan_done(struct net_device
*dev
)
320 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
321 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
322 struct cfg80211_bss
*bss
;
324 lockdep_assert_wiphy(wdev
->wiphy
);
329 if (wdev
->conn
->state
!= CFG80211_CONN_SCANNING
&&
330 wdev
->conn
->state
!= CFG80211_CONN_SCAN_AGAIN
)
333 bss
= cfg80211_get_conn_bss(wdev
);
335 cfg80211_put_bss(&rdev
->wiphy
, bss
);
337 schedule_work(&rdev
->conn_work
);
340 void cfg80211_sme_rx_auth(struct wireless_dev
*wdev
, const u8
*buf
, size_t len
)
342 struct wiphy
*wiphy
= wdev
->wiphy
;
343 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
344 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
345 u16 status_code
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
347 lockdep_assert_wiphy(wdev
->wiphy
);
349 if (!wdev
->conn
|| wdev
->conn
->state
== CFG80211_CONN_CONNECTED
)
352 if (status_code
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
&&
353 wdev
->conn
->auto_auth
&&
354 wdev
->conn
->params
.auth_type
!= NL80211_AUTHTYPE_NETWORK_EAP
) {
355 /* select automatically between only open, shared, leap */
356 switch (wdev
->conn
->params
.auth_type
) {
357 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
358 if (wdev
->connect_keys
)
359 wdev
->conn
->params
.auth_type
=
360 NL80211_AUTHTYPE_SHARED_KEY
;
362 wdev
->conn
->params
.auth_type
=
363 NL80211_AUTHTYPE_NETWORK_EAP
;
365 case NL80211_AUTHTYPE_SHARED_KEY
:
366 wdev
->conn
->params
.auth_type
=
367 NL80211_AUTHTYPE_NETWORK_EAP
;
371 wdev
->conn
->params
.auth_type
=
372 NL80211_AUTHTYPE_OPEN_SYSTEM
;
375 wdev
->conn
->state
= CFG80211_CONN_AUTHENTICATE_NEXT
;
376 schedule_work(&rdev
->conn_work
);
377 } else if (status_code
!= WLAN_STATUS_SUCCESS
) {
378 struct cfg80211_connect_resp_params cr
;
380 memset(&cr
, 0, sizeof(cr
));
381 cr
.status
= status_code
;
382 cr
.links
[0].bssid
= mgmt
->bssid
;
383 cr
.timeout_reason
= NL80211_TIMEOUT_UNSPECIFIED
;
384 __cfg80211_connect_result(wdev
->netdev
, &cr
, false);
385 } else if (wdev
->conn
->state
== CFG80211_CONN_AUTHENTICATING
) {
386 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
387 schedule_work(&rdev
->conn_work
);
391 bool cfg80211_sme_rx_assoc_resp(struct wireless_dev
*wdev
, u16 status
)
393 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
398 if (status
== WLAN_STATUS_SUCCESS
) {
399 wdev
->conn
->state
= CFG80211_CONN_CONNECTED
;
403 if (wdev
->conn
->prev_bssid_valid
) {
405 * Some stupid APs don't accept reassoc, so we
406 * need to fall back to trying regular assoc;
407 * return true so no event is sent to userspace.
409 wdev
->conn
->prev_bssid_valid
= false;
410 wdev
->conn
->state
= CFG80211_CONN_ASSOCIATE_NEXT
;
411 schedule_work(&rdev
->conn_work
);
415 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED
;
416 schedule_work(&rdev
->conn_work
);
420 void cfg80211_sme_deauth(struct wireless_dev
*wdev
)
422 cfg80211_sme_free(wdev
);
425 void cfg80211_sme_auth_timeout(struct wireless_dev
*wdev
)
427 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
432 wdev
->conn
->state
= CFG80211_CONN_AUTH_FAILED_TIMEOUT
;
433 schedule_work(&rdev
->conn_work
);
436 void cfg80211_sme_disassoc(struct wireless_dev
*wdev
)
438 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
443 wdev
->conn
->state
= CFG80211_CONN_DEAUTH
;
444 schedule_work(&rdev
->conn_work
);
447 void cfg80211_sme_assoc_timeout(struct wireless_dev
*wdev
)
449 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
454 wdev
->conn
->state
= CFG80211_CONN_ASSOC_FAILED_TIMEOUT
;
455 schedule_work(&rdev
->conn_work
);
458 void cfg80211_sme_abandon_assoc(struct wireless_dev
*wdev
)
460 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
465 wdev
->conn
->state
= CFG80211_CONN_ABANDON
;
466 schedule_work(&rdev
->conn_work
);
469 static void cfg80211_wdev_release_bsses(struct wireless_dev
*wdev
)
473 for_each_valid_link(wdev
, link
) {
474 if (!wdev
->links
[link
].client
.current_bss
)
476 cfg80211_unhold_bss(wdev
->links
[link
].client
.current_bss
);
477 cfg80211_put_bss(wdev
->wiphy
,
478 &wdev
->links
[link
].client
.current_bss
->pub
);
479 wdev
->links
[link
].client
.current_bss
= NULL
;
483 void cfg80211_wdev_release_link_bsses(struct wireless_dev
*wdev
, u16 link_mask
)
487 for_each_valid_link(wdev
, link
) {
488 if (!wdev
->links
[link
].client
.current_bss
||
489 !(link_mask
& BIT(link
)))
491 cfg80211_unhold_bss(wdev
->links
[link
].client
.current_bss
);
492 cfg80211_put_bss(wdev
->wiphy
,
493 &wdev
->links
[link
].client
.current_bss
->pub
);
494 wdev
->links
[link
].client
.current_bss
= NULL
;
498 static int cfg80211_sme_get_conn_ies(struct wireless_dev
*wdev
,
499 const u8
*ies
, size_t ies_len
,
500 const u8
**out_ies
, size_t *out_ies_len
)
502 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
506 if (!rdev
->wiphy
.extended_capabilities_len
||
507 (ies
&& cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY
, ies
, ies_len
))) {
508 *out_ies
= kmemdup(ies
, ies_len
, GFP_KERNEL
);
511 *out_ies_len
= ies_len
;
515 buf
= kmalloc(ies_len
+ rdev
->wiphy
.extended_capabilities_len
+ 2,
521 static const u8 before_extcapa
[] = {
522 /* not listing IEs expected to be created by driver */
525 WLAN_EID_RRM_ENABLED_CAPABILITIES
,
526 WLAN_EID_MOBILITY_DOMAIN
,
527 WLAN_EID_SUPPORTED_REGULATORY_CLASSES
,
528 WLAN_EID_BSS_COEX_2040
,
531 offs
= ieee80211_ie_split(ies
, ies_len
, before_extcapa
,
532 ARRAY_SIZE(before_extcapa
), 0);
533 memcpy(buf
, ies
, offs
);
534 /* leave a whole for extended capabilities IE */
535 memcpy(buf
+ offs
+ rdev
->wiphy
.extended_capabilities_len
+ 2,
536 ies
+ offs
, ies_len
- offs
);
541 /* place extended capabilities IE (with only driver capabilities) */
542 buf
[offs
] = WLAN_EID_EXT_CAPABILITY
;
543 buf
[offs
+ 1] = rdev
->wiphy
.extended_capabilities_len
;
544 memcpy(buf
+ offs
+ 2,
545 rdev
->wiphy
.extended_capabilities
,
546 rdev
->wiphy
.extended_capabilities_len
);
549 *out_ies_len
= ies_len
+ rdev
->wiphy
.extended_capabilities_len
+ 2;
554 static int cfg80211_sme_connect(struct wireless_dev
*wdev
,
555 struct cfg80211_connect_params
*connect
,
556 const u8
*prev_bssid
)
558 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
559 struct cfg80211_bss
*bss
;
562 if (!rdev
->ops
->auth
|| !rdev
->ops
->assoc
)
565 cfg80211_wdev_release_bsses(wdev
);
567 if (wdev
->connected
) {
568 cfg80211_sme_free(wdev
);
569 wdev
->connected
= false;
575 wdev
->conn
= kzalloc(sizeof(*wdev
->conn
), GFP_KERNEL
);
580 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
582 memcpy(&wdev
->conn
->params
, connect
, sizeof(*connect
));
583 if (connect
->bssid
) {
584 wdev
->conn
->params
.bssid
= wdev
->conn
->bssid
;
585 memcpy(wdev
->conn
->bssid
, connect
->bssid
, ETH_ALEN
);
588 if (cfg80211_sme_get_conn_ies(wdev
, connect
->ie
, connect
->ie_len
,
590 &wdev
->conn
->params
.ie_len
)) {
595 wdev
->conn
->params
.ie
= wdev
->conn
->ie
;
597 if (connect
->auth_type
== NL80211_AUTHTYPE_AUTOMATIC
) {
598 wdev
->conn
->auto_auth
= true;
599 /* start with open system ... should mostly work */
600 wdev
->conn
->params
.auth_type
=
601 NL80211_AUTHTYPE_OPEN_SYSTEM
;
603 wdev
->conn
->auto_auth
= false;
606 wdev
->conn
->params
.ssid
= wdev
->u
.client
.ssid
;
607 wdev
->conn
->params
.ssid_len
= wdev
->u
.client
.ssid_len
;
609 /* see if we have the bss already */
610 bss
= cfg80211_get_bss(wdev
->wiphy
, wdev
->conn
->params
.channel
,
611 wdev
->conn
->params
.bssid
,
612 wdev
->conn
->params
.ssid
,
613 wdev
->conn
->params
.ssid_len
,
615 IEEE80211_PRIVACY(wdev
->conn
->params
.privacy
));
618 memcpy(wdev
->conn
->prev_bssid
, prev_bssid
, ETH_ALEN
);
619 wdev
->conn
->prev_bssid_valid
= true;
622 /* we're good if we have a matching bss struct */
624 enum nl80211_timeout_reason treason
;
626 cfg80211_step_auth_next(wdev
->conn
, bss
);
627 err
= cfg80211_conn_do_work(wdev
, &treason
);
628 cfg80211_put_bss(wdev
->wiphy
, bss
);
630 /* otherwise we'll need to scan for the AP first */
631 err
= cfg80211_conn_scan(wdev
);
634 * If we can't scan right now, then we need to scan again
635 * after the current scan finished, since the parameters
636 * changed (unless we find a good AP anyway).
640 wdev
->conn
->state
= CFG80211_CONN_SCAN_AGAIN
;
645 cfg80211_sme_free(wdev
);
650 static int cfg80211_sme_disconnect(struct wireless_dev
*wdev
, u16 reason
)
652 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
658 if (!rdev
->ops
->deauth
)
661 if (wdev
->conn
->state
== CFG80211_CONN_SCANNING
||
662 wdev
->conn
->state
== CFG80211_CONN_SCAN_AGAIN
) {
667 /* wdev->conn->params.bssid must be set if > SCANNING */
668 err
= cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
669 wdev
->conn
->params
.bssid
,
670 NULL
, 0, reason
, false);
672 cfg80211_sme_free(wdev
);
677 * code shared for in-device and software SME
680 static bool cfg80211_is_all_idle(void)
682 struct cfg80211_registered_device
*rdev
;
683 struct wireless_dev
*wdev
;
684 bool is_all_idle
= true;
687 * All devices must be idle as otherwise if you are actively
688 * scanning some new beacon hints could be learned and would
689 * count as new regulatory hints.
690 * Also if there is any other active beaconing interface we
691 * need not issue a disconnect hint and reset any info such
692 * as chan dfs state, etc.
694 for_each_rdev(rdev
) {
695 wiphy_lock(&rdev
->wiphy
);
696 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
) {
697 if (wdev
->conn
|| wdev
->connected
||
698 cfg80211_beaconing_iface_active(wdev
))
701 wiphy_unlock(&rdev
->wiphy
);
707 static void disconnect_work(struct work_struct
*work
)
710 if (cfg80211_is_all_idle())
711 regulatory_hint_disconnect();
715 DECLARE_WORK(cfg80211_disconnect_work
, disconnect_work
);
718 cfg80211_connect_result_release_bsses(struct wireless_dev
*wdev
,
719 struct cfg80211_connect_resp_params
*cr
)
723 for_each_valid_link(cr
, link
) {
724 if (!cr
->links
[link
].bss
)
726 cfg80211_unhold_bss(bss_from_pub(cr
->links
[link
].bss
));
727 cfg80211_put_bss(wdev
->wiphy
, cr
->links
[link
].bss
);
732 * API calls for drivers implementing connect/disconnect and
736 /* This method must consume bss one way or another */
737 void __cfg80211_connect_result(struct net_device
*dev
,
738 struct cfg80211_connect_resp_params
*cr
,
741 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
742 const struct element
*country_elem
= NULL
;
743 const struct element
*ssid
;
744 const u8
*country_data
;
746 #ifdef CONFIG_CFG80211_WEXT
747 union iwreq_data wrqu
;
750 const u8
*connected_addr
;
751 bool bss_not_found
= false;
753 lockdep_assert_wiphy(wdev
->wiphy
);
755 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
756 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
759 if (cr
->valid_links
) {
760 if (WARN_ON(!cr
->ap_mld_addr
))
763 for_each_valid_link(cr
, link
) {
764 if (WARN_ON(!cr
->links
[link
].addr
))
768 if (WARN_ON(wdev
->connect_keys
))
772 wdev
->unprot_beacon_reported
= 0;
773 nl80211_send_connect_result(wiphy_to_rdev(wdev
->wiphy
), dev
, cr
,
775 connected_addr
= cr
->valid_links
? cr
->ap_mld_addr
: cr
->links
[0].bssid
;
777 #ifdef CONFIG_CFG80211_WEXT
778 if (wextev
&& !cr
->valid_links
) {
779 if (cr
->req_ie
&& cr
->status
== WLAN_STATUS_SUCCESS
) {
780 memset(&wrqu
, 0, sizeof(wrqu
));
781 wrqu
.data
.length
= cr
->req_ie_len
;
782 wireless_send_event(dev
, IWEVASSOCREQIE
, &wrqu
,
786 if (cr
->resp_ie
&& cr
->status
== WLAN_STATUS_SUCCESS
) {
787 memset(&wrqu
, 0, sizeof(wrqu
));
788 wrqu
.data
.length
= cr
->resp_ie_len
;
789 wireless_send_event(dev
, IWEVASSOCRESPIE
, &wrqu
,
793 memset(&wrqu
, 0, sizeof(wrqu
));
794 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
795 if (connected_addr
&& cr
->status
== WLAN_STATUS_SUCCESS
) {
796 memcpy(wrqu
.ap_addr
.sa_data
, connected_addr
, ETH_ALEN
);
797 memcpy(wdev
->wext
.prev_bssid
, connected_addr
, ETH_ALEN
);
798 wdev
->wext
.prev_bssid_valid
= true;
800 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
804 if (cr
->status
== WLAN_STATUS_SUCCESS
) {
805 if (!wiphy_to_rdev(wdev
->wiphy
)->ops
->connect
) {
806 for_each_valid_link(cr
, link
) {
807 if (WARN_ON_ONCE(!cr
->links
[link
].bss
))
812 for_each_valid_link(cr
, link
) {
813 /* don't do extra lookups for failures */
814 if (cr
->links
[link
].status
!= WLAN_STATUS_SUCCESS
)
817 if (cr
->links
[link
].bss
)
820 cr
->links
[link
].bss
=
821 cfg80211_get_bss(wdev
->wiphy
, NULL
,
822 cr
->links
[link
].bssid
,
824 wdev
->u
.client
.ssid_len
,
826 IEEE80211_PRIVACY_ANY
);
827 if (!cr
->links
[link
].bss
) {
828 bss_not_found
= true;
831 cfg80211_hold_bss(bss_from_pub(cr
->links
[link
].bss
));
835 cfg80211_wdev_release_bsses(wdev
);
837 if (cr
->status
!= WLAN_STATUS_SUCCESS
) {
838 kfree_sensitive(wdev
->connect_keys
);
839 wdev
->connect_keys
= NULL
;
840 wdev
->u
.client
.ssid_len
= 0;
841 wdev
->conn_owner_nlportid
= 0;
842 cfg80211_connect_result_release_bsses(wdev
, cr
);
843 cfg80211_sme_free(wdev
);
847 if (WARN_ON(bss_not_found
)) {
848 cfg80211_connect_result_release_bsses(wdev
, cr
);
852 memset(wdev
->links
, 0, sizeof(wdev
->links
));
853 for_each_valid_link(cr
, link
) {
854 if (cr
->links
[link
].status
== WLAN_STATUS_SUCCESS
)
856 cr
->valid_links
&= ~BIT(link
);
857 /* don't require bss pointer for failed links */
858 if (!cr
->links
[link
].bss
)
860 cfg80211_unhold_bss(bss_from_pub(cr
->links
[link
].bss
));
861 cfg80211_put_bss(wdev
->wiphy
, cr
->links
[link
].bss
);
863 wdev
->valid_links
= cr
->valid_links
;
864 for_each_valid_link(cr
, link
)
865 wdev
->links
[link
].client
.current_bss
=
866 bss_from_pub(cr
->links
[link
].bss
);
867 wdev
->connected
= true;
868 ether_addr_copy(wdev
->u
.client
.connected_addr
, connected_addr
);
869 if (cr
->valid_links
) {
870 for_each_valid_link(cr
, link
)
871 memcpy(wdev
->links
[link
].addr
, cr
->links
[link
].addr
,
875 cfg80211_upload_connect_keys(wdev
);
878 for_each_valid_link(cr
, link
) {
880 ieee80211_bss_get_elem(cr
->links
[link
].bss
,
890 country_datalen
= country_elem
->datalen
;
891 country_data
= kmemdup(country_elem
->data
, country_datalen
, GFP_ATOMIC
);
897 regulatory_hint_country_ie(wdev
->wiphy
,
898 cr
->links
[link
].bss
->channel
->band
,
899 country_data
, country_datalen
);
902 if (!wdev
->u
.client
.ssid_len
) {
904 for_each_valid_link(cr
, link
) {
905 ssid
= ieee80211_bss_get_elem(cr
->links
[link
].bss
,
908 if (!ssid
|| !ssid
->datalen
)
911 memcpy(wdev
->u
.client
.ssid
, ssid
->data
, ssid
->datalen
);
912 wdev
->u
.client
.ssid_len
= ssid
->datalen
;
920 for_each_valid_link(cr
, link
)
921 cfg80211_put_bss(wdev
->wiphy
, cr
->links
[link
].bss
);
924 static void cfg80211_update_link_bss(struct wireless_dev
*wdev
,
925 struct cfg80211_bss
**bss
)
927 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
928 struct cfg80211_internal_bss
*ibss
;
933 ibss
= bss_from_pub(*bss
);
934 if (list_empty(&ibss
->list
)) {
935 struct cfg80211_bss
*found
= NULL
, *tmp
= *bss
;
937 found
= cfg80211_get_bss(wdev
->wiphy
, NULL
,
940 wdev
->u
.client
.ssid_len
,
942 IEEE80211_PRIVACY_ANY
);
944 /* The same BSS is already updated so use it
945 * instead, as it has latest info.
949 /* Update with BSS provided by driver, it will
950 * be freshly added and ref cnted, we can free
953 * signal_valid can be false, as we are not
954 * expecting the BSS to be found.
956 * keep the old timestamp to avoid confusion
958 cfg80211_bss_update(rdev
, ibss
, false,
962 cfg80211_put_bss(wdev
->wiphy
, tmp
);
966 /* Consumes bss object(s) one way or another */
967 void cfg80211_connect_done(struct net_device
*dev
,
968 struct cfg80211_connect_resp_params
*params
,
971 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
972 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
973 struct cfg80211_event
*ev
;
976 size_t link_info_size
= 0;
979 for_each_valid_link(params
, link
) {
980 cfg80211_update_link_bss(wdev
, ¶ms
->links
[link
].bss
);
981 link_info_size
+= params
->links
[link
].bssid
? ETH_ALEN
: 0;
982 link_info_size
+= params
->links
[link
].addr
? ETH_ALEN
: 0;
985 ev
= kzalloc(sizeof(*ev
) + (params
->ap_mld_addr
? ETH_ALEN
: 0) +
986 params
->req_ie_len
+ params
->resp_ie_len
+
987 params
->fils
.kek_len
+ params
->fils
.pmk_len
+
988 (params
->fils
.pmkid
? WLAN_PMKID_LEN
: 0) + link_info_size
,
992 for_each_valid_link(params
, link
)
993 cfg80211_put_bss(wdev
->wiphy
,
994 params
->links
[link
].bss
);
998 ev
->type
= EVENT_CONNECT_RESULT
;
999 next
= ((u8
*)ev
) + sizeof(*ev
);
1000 if (params
->ap_mld_addr
) {
1001 ev
->cr
.ap_mld_addr
= next
;
1002 memcpy((void *)ev
->cr
.ap_mld_addr
, params
->ap_mld_addr
,
1006 if (params
->req_ie_len
) {
1007 ev
->cr
.req_ie
= next
;
1008 ev
->cr
.req_ie_len
= params
->req_ie_len
;
1009 memcpy((void *)ev
->cr
.req_ie
, params
->req_ie
,
1010 params
->req_ie_len
);
1011 next
+= params
->req_ie_len
;
1013 if (params
->resp_ie_len
) {
1014 ev
->cr
.resp_ie
= next
;
1015 ev
->cr
.resp_ie_len
= params
->resp_ie_len
;
1016 memcpy((void *)ev
->cr
.resp_ie
, params
->resp_ie
,
1017 params
->resp_ie_len
);
1018 next
+= params
->resp_ie_len
;
1020 if (params
->fils
.kek_len
) {
1021 ev
->cr
.fils
.kek
= next
;
1022 ev
->cr
.fils
.kek_len
= params
->fils
.kek_len
;
1023 memcpy((void *)ev
->cr
.fils
.kek
, params
->fils
.kek
,
1024 params
->fils
.kek_len
);
1025 next
+= params
->fils
.kek_len
;
1027 if (params
->fils
.pmk_len
) {
1028 ev
->cr
.fils
.pmk
= next
;
1029 ev
->cr
.fils
.pmk_len
= params
->fils
.pmk_len
;
1030 memcpy((void *)ev
->cr
.fils
.pmk
, params
->fils
.pmk
,
1031 params
->fils
.pmk_len
);
1032 next
+= params
->fils
.pmk_len
;
1034 if (params
->fils
.pmkid
) {
1035 ev
->cr
.fils
.pmkid
= next
;
1036 memcpy((void *)ev
->cr
.fils
.pmkid
, params
->fils
.pmkid
,
1038 next
+= WLAN_PMKID_LEN
;
1040 ev
->cr
.fils
.update_erp_next_seq_num
= params
->fils
.update_erp_next_seq_num
;
1041 if (params
->fils
.update_erp_next_seq_num
)
1042 ev
->cr
.fils
.erp_next_seq_num
= params
->fils
.erp_next_seq_num
;
1043 ev
->cr
.valid_links
= params
->valid_links
;
1044 for_each_valid_link(params
, link
) {
1045 if (params
->links
[link
].bss
)
1047 bss_from_pub(params
->links
[link
].bss
));
1048 ev
->cr
.links
[link
].bss
= params
->links
[link
].bss
;
1049 ev
->cr
.links
[link
].status
= params
->links
[link
].status
;
1051 if (params
->links
[link
].addr
) {
1052 ev
->cr
.links
[link
].addr
= next
;
1053 memcpy((void *)ev
->cr
.links
[link
].addr
,
1054 params
->links
[link
].addr
,
1058 if (params
->links
[link
].bssid
) {
1059 ev
->cr
.links
[link
].bssid
= next
;
1060 memcpy((void *)ev
->cr
.links
[link
].bssid
,
1061 params
->links
[link
].bssid
,
1066 ev
->cr
.status
= params
->status
;
1067 ev
->cr
.timeout_reason
= params
->timeout_reason
;
1069 spin_lock_irqsave(&wdev
->event_lock
, flags
);
1070 list_add_tail(&ev
->list
, &wdev
->event_list
);
1071 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
1072 queue_work(cfg80211_wq
, &rdev
->event_work
);
1074 EXPORT_SYMBOL(cfg80211_connect_done
);
1076 /* Consumes bss object one way or another */
1077 void __cfg80211_roamed(struct wireless_dev
*wdev
,
1078 struct cfg80211_roam_info
*info
)
1080 #ifdef CONFIG_CFG80211_WEXT
1081 union iwreq_data wrqu
;
1084 const u8
*connected_addr
;
1086 lockdep_assert_wiphy(wdev
->wiphy
);
1088 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
1089 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
1092 if (WARN_ON(!wdev
->connected
))
1095 if (info
->valid_links
) {
1096 if (WARN_ON(!info
->ap_mld_addr
))
1099 for_each_valid_link(info
, link
) {
1100 if (WARN_ON(!info
->links
[link
].addr
))
1105 cfg80211_wdev_release_bsses(wdev
);
1107 for_each_valid_link(info
, link
) {
1108 if (WARN_ON(!info
->links
[link
].bss
))
1112 memset(wdev
->links
, 0, sizeof(wdev
->links
));
1113 wdev
->valid_links
= info
->valid_links
;
1114 for_each_valid_link(info
, link
) {
1115 cfg80211_hold_bss(bss_from_pub(info
->links
[link
].bss
));
1116 wdev
->links
[link
].client
.current_bss
=
1117 bss_from_pub(info
->links
[link
].bss
);
1120 connected_addr
= info
->valid_links
?
1122 info
->links
[0].bss
->bssid
;
1123 ether_addr_copy(wdev
->u
.client
.connected_addr
, connected_addr
);
1124 if (info
->valid_links
) {
1125 for_each_valid_link(info
, link
)
1126 memcpy(wdev
->links
[link
].addr
, info
->links
[link
].addr
,
1129 wdev
->unprot_beacon_reported
= 0;
1130 nl80211_send_roamed(wiphy_to_rdev(wdev
->wiphy
),
1131 wdev
->netdev
, info
, GFP_KERNEL
);
1133 #ifdef CONFIG_CFG80211_WEXT
1134 if (!info
->valid_links
) {
1136 memset(&wrqu
, 0, sizeof(wrqu
));
1137 wrqu
.data
.length
= info
->req_ie_len
;
1138 wireless_send_event(wdev
->netdev
, IWEVASSOCREQIE
,
1139 &wrqu
, info
->req_ie
);
1142 if (info
->resp_ie
) {
1143 memset(&wrqu
, 0, sizeof(wrqu
));
1144 wrqu
.data
.length
= info
->resp_ie_len
;
1145 wireless_send_event(wdev
->netdev
, IWEVASSOCRESPIE
,
1146 &wrqu
, info
->resp_ie
);
1149 memset(&wrqu
, 0, sizeof(wrqu
));
1150 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1151 memcpy(wrqu
.ap_addr
.sa_data
, connected_addr
, ETH_ALEN
);
1152 memcpy(wdev
->wext
.prev_bssid
, connected_addr
, ETH_ALEN
);
1153 wdev
->wext
.prev_bssid_valid
= true;
1154 wireless_send_event(wdev
->netdev
, SIOCGIWAP
, &wrqu
, NULL
);
1160 for_each_valid_link(info
, link
)
1161 cfg80211_put_bss(wdev
->wiphy
, info
->links
[link
].bss
);
1164 /* Consumes info->links.bss object(s) one way or another */
1165 void cfg80211_roamed(struct net_device
*dev
, struct cfg80211_roam_info
*info
,
1168 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1169 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1170 struct cfg80211_event
*ev
;
1171 unsigned long flags
;
1174 size_t link_info_size
= 0;
1175 bool bss_not_found
= false;
1177 for_each_valid_link(info
, link
) {
1178 link_info_size
+= info
->links
[link
].addr
? ETH_ALEN
: 0;
1179 link_info_size
+= info
->links
[link
].bssid
? ETH_ALEN
: 0;
1181 if (info
->links
[link
].bss
)
1184 info
->links
[link
].bss
=
1185 cfg80211_get_bss(wdev
->wiphy
,
1186 info
->links
[link
].channel
,
1187 info
->links
[link
].bssid
,
1188 wdev
->u
.client
.ssid
,
1189 wdev
->u
.client
.ssid_len
,
1190 wdev
->conn_bss_type
,
1191 IEEE80211_PRIVACY_ANY
);
1193 if (!info
->links
[link
].bss
) {
1194 bss_not_found
= true;
1199 if (WARN_ON(bss_not_found
))
1202 ev
= kzalloc(sizeof(*ev
) + info
->req_ie_len
+ info
->resp_ie_len
+
1203 info
->fils
.kek_len
+ info
->fils
.pmk_len
+
1204 (info
->fils
.pmkid
? WLAN_PMKID_LEN
: 0) +
1205 (info
->ap_mld_addr
? ETH_ALEN
: 0) + link_info_size
, gfp
);
1209 ev
->type
= EVENT_ROAMED
;
1210 next
= ((u8
*)ev
) + sizeof(*ev
);
1211 if (info
->req_ie_len
) {
1212 ev
->rm
.req_ie
= next
;
1213 ev
->rm
.req_ie_len
= info
->req_ie_len
;
1214 memcpy((void *)ev
->rm
.req_ie
, info
->req_ie
, info
->req_ie_len
);
1215 next
+= info
->req_ie_len
;
1217 if (info
->resp_ie_len
) {
1218 ev
->rm
.resp_ie
= next
;
1219 ev
->rm
.resp_ie_len
= info
->resp_ie_len
;
1220 memcpy((void *)ev
->rm
.resp_ie
, info
->resp_ie
,
1222 next
+= info
->resp_ie_len
;
1224 if (info
->fils
.kek_len
) {
1225 ev
->rm
.fils
.kek
= next
;
1226 ev
->rm
.fils
.kek_len
= info
->fils
.kek_len
;
1227 memcpy((void *)ev
->rm
.fils
.kek
, info
->fils
.kek
,
1228 info
->fils
.kek_len
);
1229 next
+= info
->fils
.kek_len
;
1231 if (info
->fils
.pmk_len
) {
1232 ev
->rm
.fils
.pmk
= next
;
1233 ev
->rm
.fils
.pmk_len
= info
->fils
.pmk_len
;
1234 memcpy((void *)ev
->rm
.fils
.pmk
, info
->fils
.pmk
,
1235 info
->fils
.pmk_len
);
1236 next
+= info
->fils
.pmk_len
;
1238 if (info
->fils
.pmkid
) {
1239 ev
->rm
.fils
.pmkid
= next
;
1240 memcpy((void *)ev
->rm
.fils
.pmkid
, info
->fils
.pmkid
,
1242 next
+= WLAN_PMKID_LEN
;
1244 ev
->rm
.fils
.update_erp_next_seq_num
= info
->fils
.update_erp_next_seq_num
;
1245 if (info
->fils
.update_erp_next_seq_num
)
1246 ev
->rm
.fils
.erp_next_seq_num
= info
->fils
.erp_next_seq_num
;
1247 if (info
->ap_mld_addr
) {
1248 ev
->rm
.ap_mld_addr
= next
;
1249 memcpy((void *)ev
->rm
.ap_mld_addr
, info
->ap_mld_addr
,
1253 ev
->rm
.valid_links
= info
->valid_links
;
1254 for_each_valid_link(info
, link
) {
1255 ev
->rm
.links
[link
].bss
= info
->links
[link
].bss
;
1257 if (info
->links
[link
].addr
) {
1258 ev
->rm
.links
[link
].addr
= next
;
1259 memcpy((void *)ev
->rm
.links
[link
].addr
,
1260 info
->links
[link
].addr
,
1265 if (info
->links
[link
].bssid
) {
1266 ev
->rm
.links
[link
].bssid
= next
;
1267 memcpy((void *)ev
->rm
.links
[link
].bssid
,
1268 info
->links
[link
].bssid
,
1274 spin_lock_irqsave(&wdev
->event_lock
, flags
);
1275 list_add_tail(&ev
->list
, &wdev
->event_list
);
1276 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
1277 queue_work(cfg80211_wq
, &rdev
->event_work
);
1281 for_each_valid_link(info
, link
)
1282 cfg80211_put_bss(wdev
->wiphy
, info
->links
[link
].bss
);
1285 EXPORT_SYMBOL(cfg80211_roamed
);
1287 void __cfg80211_port_authorized(struct wireless_dev
*wdev
, const u8
*peer_addr
,
1288 const u8
*td_bitmap
, u8 td_bitmap_len
)
1290 lockdep_assert_wiphy(wdev
->wiphy
);
1292 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
1293 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
&&
1294 wdev
->iftype
!= NL80211_IFTYPE_AP
&&
1295 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
))
1298 if (wdev
->iftype
== NL80211_IFTYPE_STATION
||
1299 wdev
->iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
1300 if (WARN_ON(!wdev
->connected
) ||
1301 WARN_ON(!ether_addr_equal(wdev
->u
.client
.connected_addr
, peer_addr
)))
1305 nl80211_send_port_authorized(wiphy_to_rdev(wdev
->wiphy
), wdev
->netdev
,
1306 peer_addr
, td_bitmap
, td_bitmap_len
);
1309 void cfg80211_port_authorized(struct net_device
*dev
, const u8
*peer_addr
,
1310 const u8
*td_bitmap
, u8 td_bitmap_len
, gfp_t gfp
)
1312 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1313 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1314 struct cfg80211_event
*ev
;
1315 unsigned long flags
;
1317 if (WARN_ON(!peer_addr
))
1320 ev
= kzalloc(sizeof(*ev
) + td_bitmap_len
, gfp
);
1324 ev
->type
= EVENT_PORT_AUTHORIZED
;
1325 memcpy(ev
->pa
.peer_addr
, peer_addr
, ETH_ALEN
);
1326 ev
->pa
.td_bitmap
= ((u8
*)ev
) + sizeof(*ev
);
1327 ev
->pa
.td_bitmap_len
= td_bitmap_len
;
1328 memcpy((void *)ev
->pa
.td_bitmap
, td_bitmap
, td_bitmap_len
);
1331 * Use the wdev event list so that if there are pending
1332 * connected/roamed events, they will be reported first.
1334 spin_lock_irqsave(&wdev
->event_lock
, flags
);
1335 list_add_tail(&ev
->list
, &wdev
->event_list
);
1336 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
1337 queue_work(cfg80211_wq
, &rdev
->event_work
);
1339 EXPORT_SYMBOL(cfg80211_port_authorized
);
1341 void __cfg80211_disconnected(struct net_device
*dev
, const u8
*ie
,
1342 size_t ie_len
, u16 reason
, bool from_ap
)
1344 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1345 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1347 #ifdef CONFIG_CFG80211_WEXT
1348 union iwreq_data wrqu
;
1351 lockdep_assert_wiphy(wdev
->wiphy
);
1353 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_STATION
&&
1354 wdev
->iftype
!= NL80211_IFTYPE_P2P_CLIENT
))
1357 cfg80211_wdev_release_bsses(wdev
);
1358 wdev
->valid_links
= 0;
1359 wdev
->connected
= false;
1360 wdev
->u
.client
.ssid_len
= 0;
1361 wdev
->conn_owner_nlportid
= 0;
1362 kfree_sensitive(wdev
->connect_keys
);
1363 wdev
->connect_keys
= NULL
;
1365 nl80211_send_disconnected(rdev
, dev
, reason
, ie
, ie_len
, from_ap
);
1367 /* stop critical protocol if supported */
1368 if (rdev
->ops
->crit_proto_stop
&& rdev
->crit_proto_nlportid
) {
1369 rdev
->crit_proto_nlportid
= 0;
1370 rdev_crit_proto_stop(rdev
, wdev
);
1374 * Delete all the keys ... pairwise keys can't really
1375 * exist any more anyway, but default keys might.
1377 if (rdev
->ops
->del_key
) {
1378 int max_key_idx
= 5;
1380 if (wiphy_ext_feature_isset(
1382 NL80211_EXT_FEATURE_BEACON_PROTECTION
) ||
1383 wiphy_ext_feature_isset(
1385 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT
))
1387 for (i
= 0; i
<= max_key_idx
; i
++)
1388 rdev_del_key(rdev
, dev
, -1, i
, false, NULL
);
1391 rdev_set_qos_map(rdev
, dev
, NULL
);
1393 #ifdef CONFIG_CFG80211_WEXT
1394 memset(&wrqu
, 0, sizeof(wrqu
));
1395 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1396 wireless_send_event(dev
, SIOCGIWAP
, &wrqu
, NULL
);
1397 wdev
->wext
.connect
.ssid_len
= 0;
1400 schedule_work(&cfg80211_disconnect_work
);
1402 cfg80211_schedule_channels_check(wdev
);
1405 void cfg80211_disconnected(struct net_device
*dev
, u16 reason
,
1406 const u8
*ie
, size_t ie_len
,
1407 bool locally_generated
, gfp_t gfp
)
1409 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1410 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1411 struct cfg80211_event
*ev
;
1412 unsigned long flags
;
1414 ev
= kzalloc(sizeof(*ev
) + ie_len
, gfp
);
1418 ev
->type
= EVENT_DISCONNECTED
;
1419 ev
->dc
.ie
= ((u8
*)ev
) + sizeof(*ev
);
1420 ev
->dc
.ie_len
= ie_len
;
1421 memcpy((void *)ev
->dc
.ie
, ie
, ie_len
);
1422 ev
->dc
.reason
= reason
;
1423 ev
->dc
.locally_generated
= locally_generated
;
1425 spin_lock_irqsave(&wdev
->event_lock
, flags
);
1426 list_add_tail(&ev
->list
, &wdev
->event_list
);
1427 spin_unlock_irqrestore(&wdev
->event_lock
, flags
);
1428 queue_work(cfg80211_wq
, &rdev
->event_work
);
1430 EXPORT_SYMBOL(cfg80211_disconnected
);
1433 * API calls for nl80211/wext compatibility code
1435 int cfg80211_connect(struct cfg80211_registered_device
*rdev
,
1436 struct net_device
*dev
,
1437 struct cfg80211_connect_params
*connect
,
1438 struct cfg80211_cached_keys
*connkeys
,
1439 const u8
*prev_bssid
)
1441 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1444 lockdep_assert_wiphy(wdev
->wiphy
);
1447 * If we have an ssid_len, we're trying to connect or are
1448 * already connected, so reject a new SSID unless it's the
1449 * same (which is the case for re-association.)
1451 if (wdev
->u
.client
.ssid_len
&&
1452 (wdev
->u
.client
.ssid_len
!= connect
->ssid_len
||
1453 memcmp(wdev
->u
.client
.ssid
, connect
->ssid
, wdev
->u
.client
.ssid_len
)))
1457 * If connected, reject (re-)association unless prev_bssid
1458 * matches the current BSSID.
1460 if (wdev
->connected
) {
1463 if (!ether_addr_equal(prev_bssid
,
1464 wdev
->u
.client
.connected_addr
))
1469 * Reject if we're in the process of connecting with WEP,
1470 * this case isn't very interesting and trying to handle
1471 * it would make the code much more complex.
1473 if (wdev
->connect_keys
)
1474 return -EINPROGRESS
;
1476 cfg80211_oper_and_ht_capa(&connect
->ht_capa_mask
,
1477 rdev
->wiphy
.ht_capa_mod_mask
);
1478 cfg80211_oper_and_vht_capa(&connect
->vht_capa_mask
,
1479 rdev
->wiphy
.vht_capa_mod_mask
);
1481 if (connkeys
&& connkeys
->def
>= 0) {
1485 idx
= connkeys
->def
;
1486 cipher
= connkeys
->params
[idx
].cipher
;
1487 /* If given a WEP key we may need it for shared key auth */
1488 if (cipher
== WLAN_CIPHER_SUITE_WEP40
||
1489 cipher
== WLAN_CIPHER_SUITE_WEP104
) {
1490 connect
->key_idx
= idx
;
1491 connect
->key
= connkeys
->params
[idx
].key
;
1492 connect
->key_len
= connkeys
->params
[idx
].key_len
;
1495 * If ciphers are not set (e.g. when going through
1496 * iwconfig), we have to set them appropriately here.
1498 if (connect
->crypto
.cipher_group
== 0)
1499 connect
->crypto
.cipher_group
= cipher
;
1501 if (connect
->crypto
.n_ciphers_pairwise
== 0) {
1502 connect
->crypto
.n_ciphers_pairwise
= 1;
1503 connect
->crypto
.ciphers_pairwise
[0] = cipher
;
1507 if (WARN_ON(connkeys
))
1510 /* connect can point to wdev->wext.connect which
1511 * can hold key data from a previous connection
1513 connect
->key
= NULL
;
1514 connect
->key_len
= 0;
1515 connect
->key_idx
= 0;
1518 wdev
->connect_keys
= connkeys
;
1519 memcpy(wdev
->u
.client
.ssid
, connect
->ssid
, connect
->ssid_len
);
1520 wdev
->u
.client
.ssid_len
= connect
->ssid_len
;
1522 wdev
->conn_bss_type
= connect
->pbss
? IEEE80211_BSS_TYPE_PBSS
:
1523 IEEE80211_BSS_TYPE_ESS
;
1525 if (!rdev
->ops
->connect
)
1526 err
= cfg80211_sme_connect(wdev
, connect
, prev_bssid
);
1528 err
= rdev_connect(rdev
, dev
, connect
);
1531 wdev
->connect_keys
= NULL
;
1533 * This could be reassoc getting refused, don't clear
1534 * ssid_len in that case.
1536 if (!wdev
->connected
)
1537 wdev
->u
.client
.ssid_len
= 0;
1544 int cfg80211_disconnect(struct cfg80211_registered_device
*rdev
,
1545 struct net_device
*dev
, u16 reason
, bool wextev
)
1547 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
1550 lockdep_assert_wiphy(wdev
->wiphy
);
1552 kfree_sensitive(wdev
->connect_keys
);
1553 wdev
->connect_keys
= NULL
;
1555 wdev
->conn_owner_nlportid
= 0;
1558 err
= cfg80211_sme_disconnect(wdev
, reason
);
1559 else if (!rdev
->ops
->disconnect
)
1560 cfg80211_mlme_down(rdev
, dev
);
1561 else if (wdev
->u
.client
.ssid_len
)
1562 err
= rdev_disconnect(rdev
, dev
, reason
);
1565 * Clear ssid_len unless we actually were fully connected,
1566 * in which case cfg80211_disconnected() will take care of
1569 if (!wdev
->connected
)
1570 wdev
->u
.client
.ssid_len
= 0;
1576 * Used to clean up after the connection / connection attempt owner socket
1579 void cfg80211_autodisconnect_wk(struct work_struct
*work
)
1581 struct wireless_dev
*wdev
=
1582 container_of(work
, struct wireless_dev
, disconnect_wk
);
1583 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
1585 wiphy_lock(wdev
->wiphy
);
1587 if (wdev
->conn_owner_nlportid
) {
1588 switch (wdev
->iftype
) {
1589 case NL80211_IFTYPE_ADHOC
:
1590 cfg80211_leave_ibss(rdev
, wdev
->netdev
, false);
1592 case NL80211_IFTYPE_AP
:
1593 case NL80211_IFTYPE_P2P_GO
:
1594 cfg80211_stop_ap(rdev
, wdev
->netdev
, -1, false);
1596 case NL80211_IFTYPE_MESH_POINT
:
1597 cfg80211_leave_mesh(rdev
, wdev
->netdev
);
1599 case NL80211_IFTYPE_STATION
:
1600 case NL80211_IFTYPE_P2P_CLIENT
:
1602 * Use disconnect_bssid if still connecting and
1603 * ops->disconnect not implemented. Otherwise we can
1604 * use cfg80211_disconnect.
1606 if (rdev
->ops
->disconnect
|| wdev
->connected
)
1607 cfg80211_disconnect(rdev
, wdev
->netdev
,
1608 WLAN_REASON_DEAUTH_LEAVING
,
1611 cfg80211_mlme_deauth(rdev
, wdev
->netdev
,
1612 wdev
->disconnect_bssid
,
1614 WLAN_REASON_DEAUTH_LEAVING
,
1622 wiphy_unlock(wdev
->wiphy
);