]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Don't register for Beacon frames for IEEE 802.11ad AP
authorDedy Lansky <qca_dlansky@qca.qualcomm.com>
Tue, 27 Dec 2016 09:25:00 +0000 (11:25 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 13 Jan 2017 13:58:01 +0000 (15:58 +0200)
Beacon frames are not supported in IEEE 802.11ad network (DMG-beacons
used instead). To allow hostapd to manage IEEE 802.11ad AP with
device_ap_sme disabled, skip nl80211_register_beacons() for IEEE
802.11ad AP.

Signed-off-by: Dedy Lansky <qca_dlansky@qca.qualcomm.com>
src/drivers/driver_nl80211.c

index dab23864c96642c68b01853573ff4e55ab3e58e7..60800792d6e4fe2ca0dc02cd896fcd68a26c7202 100644 (file)
@@ -675,6 +675,7 @@ nl80211_get_wiphy_data_ap(struct i802_bss *bss)
        struct nl80211_wiphy_data *w;
        int wiphy_idx, found = 0;
        struct i802_bss *tmp_bss;
+       u8 channel;
 
        if (bss->wiphy_data != NULL)
                return bss->wiphy_data;
@@ -694,30 +695,36 @@ nl80211_get_wiphy_data_ap(struct i802_bss *bss)
        dl_list_init(&w->bsss);
        dl_list_init(&w->drvs);
 
-       w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
-       if (!w->nl_cb) {
-               os_free(w);
-               return NULL;
-       }
-       nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
-       nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_beacon_event,
-                 w);
+       /* Beacon frames not supported in IEEE 802.11ad */
+       if (ieee80211_freq_to_chan(bss->freq, &channel) !=
+           HOSTAPD_MODE_IEEE80211AD) {
+               w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
+               if (!w->nl_cb) {
+                       os_free(w);
+                       return NULL;
+               }
+               nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
+                         no_seq_check, NULL);
+               nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
+                         process_beacon_event, w);
+
+               w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
+                                                "wiphy beacons");
+               if (w->nl_beacons == NULL) {
+                       os_free(w);
+                       return NULL;
+               }
 
-       w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
-                                        "wiphy beacons");
-       if (w->nl_beacons == NULL) {
-               os_free(w);
-               return NULL;
-       }
+               if (nl80211_register_beacons(bss->drv, w)) {
+                       nl_destroy_handles(&w->nl_beacons);
+                       os_free(w);
+                       return NULL;
+               }
 
-       if (nl80211_register_beacons(bss->drv, w)) {
-               nl_destroy_handles(&w->nl_beacons);
-               os_free(w);
-               return NULL;
+               nl80211_register_eloop_read(&w->nl_beacons,
+                                           nl80211_recv_beacons, w);
        }
 
-       nl80211_register_eloop_read(&w->nl_beacons, nl80211_recv_beacons, w);
-
        dl_list_add(&nl80211_wiphys, &w->list);
 
 add:
@@ -763,7 +770,8 @@ static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
        if (!dl_list_empty(&w->bsss))
                return;
 
-       nl80211_destroy_eloop_handle(&w->nl_beacons);
+       if (w->nl_beacons)
+               nl80211_destroy_eloop_handle(&w->nl_beacons);
 
        nl_cb_put(w->nl_cb);
        dl_list_del(&w->list);
@@ -2238,9 +2246,6 @@ static int nl80211_mgmt_subscribe_ap(struct i802_bss *bss)
        if (nl80211_register_spurious_class3(bss))
                goto out_err;
 
-       if (nl80211_get_wiphy_data_ap(bss) == NULL)
-               goto out_err;
-
        nl80211_mgmt_handle_register_eloop(bss);
        return 0;
 
@@ -2276,8 +2281,6 @@ static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
        wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
                   "(%s)", bss->nl_mgmt, reason);
        nl80211_destroy_eloop_handle(&bss->nl_mgmt);
-
-       nl80211_put_wiphy_data_ap(bss);
 }
 
 
@@ -2495,12 +2498,14 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
 }
 
 
-static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
+static int wpa_driver_nl80211_del_beacon(struct i802_bss *bss)
 {
        struct nl_msg *msg;
+       struct wpa_driver_nl80211_data *drv = bss->drv;
 
        wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
                   drv->ifindex);
+       nl80211_put_wiphy_data_ap(bss);
        msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON);
        return send_and_recv_msgs(drv, msg, NULL, NULL);
 }
@@ -2553,7 +2558,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
        nl80211_remove_monitor_interface(drv);
 
        if (is_ap_interface(drv->nlmode))
-               wpa_driver_nl80211_del_beacon(drv);
+               wpa_driver_nl80211_del_beacon(bss);
 
        if (drv->eapol_sock >= 0) {
                eloop_unregister_read_sock(drv->eapol_sock);
@@ -3778,6 +3783,8 @@ static int wpa_driver_nl80211_set_ap(void *priv,
                   beacon_set);
        if (beacon_set)
                cmd = NL80211_CMD_SET_BEACON;
+       else if (!nl80211_get_wiphy_data_ap(bss))
+               return -ENOBUFS;
 
        wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
                    params->head, params->head_len);
@@ -4709,6 +4716,7 @@ static void nl80211_teardown_ap(struct i802_bss *bss)
        else
                nl80211_mgmt_unsubscribe(bss, "AP teardown");
 
+       nl80211_put_wiphy_data_ap(bss);
        bss->beacon_set = 0;
 }
 
@@ -6745,7 +6753,7 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
                wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
                nl80211_teardown_ap(bss);
                if (!bss->added_if && !drv->first_bss->next)
-                       wpa_driver_nl80211_del_beacon(drv);
+                       wpa_driver_nl80211_del_beacon(bss);
                nl80211_destroy_bss(bss);
                if (!bss->added_if)
                        i802_set_iface_flags(bss, 0);
@@ -7107,7 +7115,7 @@ static int wpa_driver_nl80211_deinit_ap(void *priv)
        struct wpa_driver_nl80211_data *drv = bss->drv;
        if (!is_ap_interface(drv->nlmode))
                return -1;
-       wpa_driver_nl80211_del_beacon(drv);
+       wpa_driver_nl80211_del_beacon(bss);
        bss->beacon_set = 0;
 
        /*
@@ -7127,7 +7135,7 @@ static int wpa_driver_nl80211_stop_ap(void *priv)
        struct wpa_driver_nl80211_data *drv = bss->drv;
        if (!is_ap_interface(drv->nlmode))
                return -1;
-       wpa_driver_nl80211_del_beacon(drv);
+       wpa_driver_nl80211_del_beacon(bss);
        bss->beacon_set = 0;
        return 0;
 }