nl80211: Don't register for Beacon frames for IEEE 802.11ad AP

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>
This commit is contained in:
Dedy Lansky 2016-12-27 11:25:00 +02:00 committed by Jouni Malinen
parent a2aa21a3bf
commit a70cd0db87

View file

@ -675,6 +675,7 @@ nl80211_get_wiphy_data_ap(struct i802_bss *bss)
struct nl80211_wiphy_data *w; struct nl80211_wiphy_data *w;
int wiphy_idx, found = 0; int wiphy_idx, found = 0;
struct i802_bss *tmp_bss; struct i802_bss *tmp_bss;
u8 channel;
if (bss->wiphy_data != NULL) if (bss->wiphy_data != NULL)
return bss->wiphy_data; return bss->wiphy_data;
@ -694,29 +695,35 @@ nl80211_get_wiphy_data_ap(struct i802_bss *bss)
dl_list_init(&w->bsss); dl_list_init(&w->bsss);
dl_list_init(&w->drvs); dl_list_init(&w->drvs);
w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT); /* Beacon frames not supported in IEEE 802.11ad */
if (!w->nl_cb) { if (ieee80211_freq_to_chan(bss->freq, &channel) !=
os_free(w); HOSTAPD_MODE_IEEE80211AD) {
return NULL; w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
} if (!w->nl_cb) {
nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); os_free(w);
nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_beacon_event, return NULL;
w); }
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, w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
"wiphy beacons"); "wiphy beacons");
if (w->nl_beacons == NULL) { if (w->nl_beacons == NULL) {
os_free(w); os_free(w);
return NULL; return NULL;
} }
if (nl80211_register_beacons(bss->drv, w)) { if (nl80211_register_beacons(bss->drv, w)) {
nl_destroy_handles(&w->nl_beacons); nl_destroy_handles(&w->nl_beacons);
os_free(w); os_free(w);
return NULL; 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); dl_list_add(&nl80211_wiphys, &w->list);
@ -763,7 +770,8 @@ static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
if (!dl_list_empty(&w->bsss)) if (!dl_list_empty(&w->bsss))
return; 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); nl_cb_put(w->nl_cb);
dl_list_del(&w->list); 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)) if (nl80211_register_spurious_class3(bss))
goto out_err; goto out_err;
if (nl80211_get_wiphy_data_ap(bss) == NULL)
goto out_err;
nl80211_mgmt_handle_register_eloop(bss); nl80211_mgmt_handle_register_eloop(bss);
return 0; 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 " wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
"(%s)", bss->nl_mgmt, reason); "(%s)", bss->nl_mgmt, reason);
nl80211_destroy_eloop_handle(&bss->nl_mgmt); 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 nl_msg *msg;
struct wpa_driver_nl80211_data *drv = bss->drv;
wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
drv->ifindex); drv->ifindex);
nl80211_put_wiphy_data_ap(bss);
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON); msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON);
return send_and_recv_msgs(drv, msg, NULL, NULL); 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); nl80211_remove_monitor_interface(drv);
if (is_ap_interface(drv->nlmode)) if (is_ap_interface(drv->nlmode))
wpa_driver_nl80211_del_beacon(drv); wpa_driver_nl80211_del_beacon(bss);
if (drv->eapol_sock >= 0) { if (drv->eapol_sock >= 0) {
eloop_unregister_read_sock(drv->eapol_sock); eloop_unregister_read_sock(drv->eapol_sock);
@ -3778,6 +3783,8 @@ static int wpa_driver_nl80211_set_ap(void *priv,
beacon_set); beacon_set);
if (beacon_set) if (beacon_set)
cmd = NL80211_CMD_SET_BEACON; cmd = NL80211_CMD_SET_BEACON;
else if (!nl80211_get_wiphy_data_ap(bss))
return -ENOBUFS;
wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head", wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
params->head, params->head_len); params->head, params->head_len);
@ -4709,6 +4716,7 @@ static void nl80211_teardown_ap(struct i802_bss *bss)
else else
nl80211_mgmt_unsubscribe(bss, "AP teardown"); nl80211_mgmt_unsubscribe(bss, "AP teardown");
nl80211_put_wiphy_data_ap(bss);
bss->beacon_set = 0; 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"); wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
nl80211_teardown_ap(bss); nl80211_teardown_ap(bss);
if (!bss->added_if && !drv->first_bss->next) if (!bss->added_if && !drv->first_bss->next)
wpa_driver_nl80211_del_beacon(drv); wpa_driver_nl80211_del_beacon(bss);
nl80211_destroy_bss(bss); nl80211_destroy_bss(bss);
if (!bss->added_if) if (!bss->added_if)
i802_set_iface_flags(bss, 0); 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; struct wpa_driver_nl80211_data *drv = bss->drv;
if (!is_ap_interface(drv->nlmode)) if (!is_ap_interface(drv->nlmode))
return -1; return -1;
wpa_driver_nl80211_del_beacon(drv); wpa_driver_nl80211_del_beacon(bss);
bss->beacon_set = 0; 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; struct wpa_driver_nl80211_data *drv = bss->drv;
if (!is_ap_interface(drv->nlmode)) if (!is_ap_interface(drv->nlmode))
return -1; return -1;
wpa_driver_nl80211_del_beacon(drv); wpa_driver_nl80211_del_beacon(bss);
bss->beacon_set = 0; bss->beacon_set = 0;
return 0; return 0;
} }