Commit ed9d01026f156db2d638cbb045231c7a8fde877d

Authored by Jouni Malinen
Committed by John W. Linville
1 parent 79d2b1570b

cfg80211: Use consistent BSS matching between scan and sme

cfg80211 scan code adds separate BSS entries if the same BSS shows up
on multiple channels. However, sme implementation does not use the
frequency when fetching the BSS entry. Fix this by adding channel
information to cfg80211_roamed() and include it in cfg80211_get_bss()
calls.

Please note that drivers using cfg80211_roamed() need to be modified to
fully implement this fix. This commit includes only minimal changes to
avoid compilation issues; it maintains the old (broken) behavior for
most drivers. ath6kl was the only one that I could test, so I updated
it to provide the operating frequency in the roamed event.

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

Showing 9 changed files with 31 additions and 15 deletions Side-by-side Diff

drivers/net/wireless/iwmc3200wifi/rx.c
... ... @@ -565,7 +565,7 @@
565 565 if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
566 566 && iwm->conf.mode == UMAC_MODE_BSS) {
567 567 cancel_delayed_work(&iwm->disconnect);
568   - cfg80211_roamed(iwm_to_ndev(iwm),
  568 + cfg80211_roamed(iwm_to_ndev(iwm), NULL,
569 569 complete->bssid,
570 570 iwm->req_ie, iwm->req_ie_len,
571 571 iwm->resp_ie, iwm->resp_ie_len,
... ... @@ -586,7 +586,7 @@
586 586 WLAN_STATUS_SUCCESS,
587 587 GFP_KERNEL);
588 588 else
589   - cfg80211_roamed(iwm_to_ndev(iwm),
  589 + cfg80211_roamed(iwm_to_ndev(iwm), NULL,
590 590 complete->bssid,
591 591 iwm->req_ie, iwm->req_ie_len,
592 592 iwm->resp_ie, iwm->resp_ie_len,
drivers/net/wireless/rndis_wlan.c
... ... @@ -2830,7 +2830,8 @@
2830 2830 req_ie_len, resp_ie,
2831 2831 resp_ie_len, 0, GFP_KERNEL);
2832 2832 else
2833   - cfg80211_roamed(usbdev->net, bssid, req_ie, req_ie_len,
  2833 + cfg80211_roamed(usbdev->net, NULL, bssid,
  2834 + req_ie, req_ie_len,
2834 2835 resp_ie, resp_ie_len, GFP_KERNEL);
2835 2836 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
2836 2837 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
drivers/staging/ath6kl/os/linux/cfg80211.c
... ... @@ -570,7 +570,7 @@
570 570 WLAN_STATUS_SUCCESS, GFP_KERNEL);
571 571 } else {
572 572 /* inform roam event to cfg80211 */
573   - cfg80211_roamed(ar->arNetDev, bssid,
  573 + cfg80211_roamed(ar->arNetDev, ibss_channel, bssid,
574 574 assocReqIe, assocReqLen,
575 575 assocRespIe, assocRespLen,
576 576 GFP_KERNEL);
drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
... ... @@ -2630,7 +2630,7 @@
2630 2630 wl_get_assoc_ies(wl);
2631 2631 memcpy(&wl->bssid, &e->addr, ETH_ALEN);
2632 2632 wl_update_bss_info(wl);
2633   - cfg80211_roamed(ndev,
  2633 + cfg80211_roamed(ndev, NULL,
2634 2634 (u8 *)&wl->bssid,
2635 2635 conn_info->req_ie, conn_info->req_ie_len,
2636 2636 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
... ... @@ -2663,7 +2663,7 @@
2663 2663 WL_DBG("Report connect result - connection %s\n",
2664 2664 completed ? "succeeded" : "failed");
2665 2665 } else {
2666   - cfg80211_roamed(ndev,
  2666 + cfg80211_roamed(ndev, NULL,
2667 2667 (u8 *)&wl->bssid,
2668 2668 conn_info->req_ie, conn_info->req_ie_len,
2669 2669 conn_info->resp_ie, conn_info->resp_ie_len,
drivers/staging/wlan-ng/cfg80211.c
... ... @@ -695,7 +695,7 @@
695 695  
696 696 void prism2_roamed(wlandevice_t *wlandev)
697 697 {
698   - cfg80211_roamed(wlandev->netdev, wlandev->bssid,
  698 + cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid,
699 699 NULL, 0, NULL, 0, GFP_KERNEL);
700 700 }
701 701  
include/net/cfg80211.h
... ... @@ -2878,6 +2878,7 @@
2878 2878 * cfg80211_roamed - notify cfg80211 of roaming
2879 2879 *
2880 2880 * @dev: network device
  2881 + * @channel: the channel of the new AP
2881 2882 * @bssid: the BSSID of the new AP
2882 2883 * @req_ie: association request IEs (maybe be %NULL)
2883 2884 * @req_ie_len: association request IEs length
... ... @@ -2888,7 +2889,9 @@
2888 2889 * It should be called by the underlying driver whenever it roamed
2889 2890 * from one AP to another while connected.
2890 2891 */
2891   -void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
  2892 +void cfg80211_roamed(struct net_device *dev,
  2893 + struct ieee80211_channel *channel,
  2894 + const u8 *bssid,
2892 2895 const u8 *req_ie, size_t req_ie_len,
2893 2896 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
2894 2897  
... ... @@ -245,6 +245,7 @@
245 245 u16 status;
246 246 } cr;
247 247 struct {
  248 + struct ieee80211_channel *channel;
248 249 u8 bssid[ETH_ALEN];
249 250 const u8 *req_ie;
250 251 const u8 *resp_ie;
... ... @@ -392,7 +393,9 @@
392 393 int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
393 394 struct net_device *dev, u16 reason,
394 395 bool wextev);
395   -void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
  396 +void __cfg80211_roamed(struct wireless_dev *wdev,
  397 + struct ieee80211_channel *channel,
  398 + const u8 *bssid,
396 399 const u8 *req_ie, size_t req_ie_len,
397 400 const u8 *resp_ie, size_t resp_ie_len);
398 401 int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
... ... @@ -250,7 +250,8 @@
250 250 if (wdev->conn->params.privacy)
251 251 capa |= WLAN_CAPABILITY_PRIVACY;
252 252  
253   - bss = cfg80211_get_bss(wdev->wiphy, NULL, wdev->conn->params.bssid,
  253 + bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
  254 + wdev->conn->params.bssid,
254 255 wdev->conn->params.ssid,
255 256 wdev->conn->params.ssid_len,
256 257 WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
... ... @@ -470,7 +471,10 @@
470 471 }
471 472  
472 473 if (!bss)
473   - bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
  474 + bss = cfg80211_get_bss(wdev->wiphy,
  475 + wdev->conn ? wdev->conn->params.channel :
  476 + NULL,
  477 + bssid,
474 478 wdev->ssid, wdev->ssid_len,
475 479 WLAN_CAPABILITY_ESS,
476 480 WLAN_CAPABILITY_ESS);
... ... @@ -538,7 +542,9 @@
538 542 }
539 543 EXPORT_SYMBOL(cfg80211_connect_result);
540 544  
541   -void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
  545 +void __cfg80211_roamed(struct wireless_dev *wdev,
  546 + struct ieee80211_channel *channel,
  547 + const u8 *bssid,
542 548 const u8 *req_ie, size_t req_ie_len,
543 549 const u8 *resp_ie, size_t resp_ie_len)
544 550 {
... ... @@ -565,7 +571,7 @@
565 571 cfg80211_put_bss(&wdev->current_bss->pub);
566 572 wdev->current_bss = NULL;
567 573  
568   - bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
  574 + bss = cfg80211_get_bss(wdev->wiphy, channel, bssid,
569 575 wdev->ssid, wdev->ssid_len,
570 576 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
571 577  
... ... @@ -603,7 +609,9 @@
603 609 #endif
604 610 }
605 611  
606   -void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
  612 +void cfg80211_roamed(struct net_device *dev,
  613 + struct ieee80211_channel *channel,
  614 + const u8 *bssid,
607 615 const u8 *req_ie, size_t req_ie_len,
608 616 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
609 617 {
... ... @@ -619,6 +627,7 @@
619 627 return;
620 628  
621 629 ev->type = EVENT_ROAMED;
  630 + ev->rm.channel = channel;
622 631 memcpy(ev->rm.bssid, bssid, ETH_ALEN);
623 632 ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
624 633 ev->rm.req_ie_len = req_ie_len;
... ... @@ -746,7 +746,7 @@
746 746 NULL);
747 747 break;
748 748 case EVENT_ROAMED:
749   - __cfg80211_roamed(wdev, ev->rm.bssid,
  749 + __cfg80211_roamed(wdev, ev->rm.channel, ev->rm.bssid,
750 750 ev->rm.req_ie, ev->rm.req_ie_len,
751 751 ev->rm.resp_ie, ev->rm.resp_ie_len);
752 752 break;