Its not DAWN related, but it is triggered by DAWN doing its thing. I would expect this same error is happening with usteer as well. Its also not YET fixed in any later OpenWRT version.
The issue is in hostapd, and in particular the patches made to it to get BSS Transition Management responses sent over ubus. Its an uninitialized variable. If the response is a WNM_BSS_TM_ACCEPT
type response, everything works fine. But a rejection of the transition request or an error response will fail to initialize the *target_bssid
variable. If it happens to be NULL on the stack, it will just work by luck. If its some other low value (I was seeing 5) then it will cause a segfault, if its a high value it will be an invalid response with random garbage in the target_bssid
to dawn/usteer (Only Accept has a target BSS).
I will post a proper patch, but if anyone wants to fix their WiFi crashing on 21.02 with band steering enabled. Replace the patch at package/network/services/hostsapd/patches/600-ubus_support.patch with the following file, and rebuild OpenWRT.
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -171,6 +171,11 @@ OBJS += ../src/common/hw_features_common
OBJS += ../src/eapol_auth/eapol_auth_sm.o
+ifdef CONFIG_UBUS
+CFLAGS += -DUBUS_SUPPORT
+OBJS += ../src/ap/ubus.o
+LIBS += -lubox -lubus
+endif
ifdef CONFIG_CODE_COVERAGE
CFLAGS += -O0 -fprofile-arcs -ftest-coverage
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -17,6 +17,7 @@
#include "utils/list.h"
#include "ap_config.h"
#include "drivers/driver.h"
+#include "ubus.h"
#define OCE_STA_CFON_ENABLED(hapd) \
((hapd->conf->oce & OCE_STA_CFON) && \
@@ -80,7 +81,7 @@ struct hapd_interfaces {
#ifdef CONFIG_CTRL_IFACE_UDP
unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN];
#endif /* CONFIG_CTRL_IFACE_UDP */
-
+ struct ubus_object ubus;
};
enum hostapd_chan_status {
@@ -154,6 +155,7 @@ struct hostapd_data {
struct hostapd_iface *iface;
struct hostapd_config *iconf;
struct hostapd_bss_config *conf;
+ struct hostapd_ubus_bss ubus;
int interface_added; /* virtual interface added for this BSS */
unsigned int started:1;
unsigned int disabled:1;
@@ -606,6 +608,7 @@ hostapd_alloc_bss_data(struct hostapd_if
struct hostapd_bss_config *bss);
int hostapd_setup_interface(struct hostapd_iface *iface);
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
void hostapd_interface_deinit(struct hostapd_iface *iface);
void hostapd_interface_free(struct hostapd_iface *iface);
struct hostapd_iface * hostapd_alloc_iface(void);
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -395,6 +395,7 @@ void hostapd_free_hapd_data(struct hosta
hapd->beacon_set_done = 0;
wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
+ hostapd_ubus_free_bss(hapd);
accounting_deinit(hapd);
hostapd_deinit_wpa(hapd);
vlan_deinit(hapd);
@@ -1417,6 +1418,8 @@ static int hostapd_setup_bss(struct host
if (hapd->driver && hapd->driver->set_operstate)
hapd->driver->set_operstate(hapd->drv_priv, 1);
+ hostapd_ubus_add_bss(hapd);
+
return 0;
}
@@ -1999,6 +2002,7 @@ static int hostapd_setup_interface_compl
if (err)
goto fail;
+ hostapd_ubus_add_iface(iface);
wpa_printf(MSG_DEBUG, "Completing interface initialization");
if (iface->freq) {
#ifdef NEED_AP_MLME
@@ -2196,6 +2200,7 @@ dfs_offload:
fail:
wpa_printf(MSG_ERROR, "Interface initialization failed");
+ hostapd_ubus_free_iface(iface);
hostapd_set_state(iface, HAPD_IFACE_DISABLED);
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
#ifdef CONFIG_FST
@@ -2669,6 +2674,7 @@ void hostapd_interface_deinit_free(struc
(unsigned int) iface->conf->num_bss);
driver = iface->bss[0]->driver;
drv_priv = iface->bss[0]->drv_priv;
+ hostapd_ubus_free_iface(iface);
hostapd_interface_deinit(iface);
wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
__func__, driver, drv_priv);
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2327,13 +2327,18 @@ static void handle_auth(struct hostapd_d
u16 auth_alg, auth_transaction, status_code;
u16 resp = WLAN_STATUS_SUCCESS;
struct sta_info *sta = NULL;
- int res, reply_res;
+ int res, reply_res, ubus_resp;
u16 fc;
const u8 *challenge = NULL;
u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
size_t resp_ies_len = 0;
u16 seq_ctrl;
struct radius_sta rad_info;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_AUTH_REQ,
+ .mgmt_frame = mgmt,
+ .ssi_signal = rssi,
+ };
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
@@ -2493,6 +2498,13 @@ static void handle_auth(struct hostapd_d
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
}
+ ubus_resp = hostapd_ubus_handle_event(hapd, &req);
+ if (ubus_resp) {
+ wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n",
+ MAC2STR(mgmt->sa));
+ resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE;
+ goto fail;
+ }
if (res == HOSTAPD_ACL_PENDING)
return;
@@ -4157,7 +4169,7 @@ static void handle_assoc(struct hostapd_
int resp = WLAN_STATUS_SUCCESS;
u16 reply_res;
const u8 *pos;
- int left, i;
+ int left, i, ubus_resp;
struct sta_info *sta;
u8 *tmp = NULL;
#ifdef CONFIG_FILS
@@ -4370,6 +4382,11 @@ static void handle_assoc(struct hostapd_
left = res;
}
#endif /* CONFIG_FILS */
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_ASSOC_REQ,
+ .mgmt_frame = mgmt,
+ .ssi_signal = rssi,
+ };
/* followed by SSID and Supported rates; and HT capabilities if 802.11n
* is used */
@@ -4468,6 +4485,14 @@ static void handle_assoc(struct hostapd_
}
#endif /* CONFIG_FILS */
+ ubus_resp = hostapd_ubus_handle_event(hapd, &req);
+ if (ubus_resp) {
+ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
+ MAC2STR(mgmt->sa));
+ resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE;
+ goto fail;
+ }
+
fail:
/*
@@ -4561,6 +4586,7 @@ static void handle_disassoc(struct hosta
wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
MAC2STR(mgmt->sa),
le_to_host16(mgmt->u.disassoc.reason_code));
+ hostapd_ubus_notify(hapd, "disassoc", mgmt->sa);
sta = ap_get_sta(hapd, mgmt->sa);
if (sta == NULL) {
@@ -4627,6 +4653,8 @@ static void handle_deauth(struct hostapd
" reason_code=%d",
MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
+ hostapd_ubus_notify(hapd, "deauth", mgmt->sa);
+
sta = ap_get_sta(hapd, mgmt->sa);
if (sta == NULL) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -814,6 +814,12 @@ void handle_probe_req(struct hostapd_dat
u16 csa_offs[2];
size_t csa_offs_len;
struct radius_sta rad_info;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_PROBE_REQ,
+ .mgmt_frame = mgmt,
+ .ssi_signal = ssi_signal,
+ .elems = &elems,
+ };
if (len < IEEE80211_HDRLEN)
return;
@@ -996,6 +1002,12 @@ void handle_probe_req(struct hostapd_dat
}
#endif /* CONFIG_P2P */
+ if (hostapd_ubus_handle_event(hapd, &req)) {
+ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n",
+ MAC2STR(mgmt->sa));
+ return;
+ }
+
/* TODO: verify that supp_rates contains at least one matching rate
* with AP configuration */
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -119,6 +119,10 @@ int hostapd_notif_assoc(struct hostapd_d
u16 reason = WLAN_REASON_UNSPECIFIED;
int status = WLAN_STATUS_SUCCESS;
const u8 *p2p_dev_addr = NULL;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_ASSOC_REQ,
+ .addr = addr,
+ };
if (addr == NULL) {
/*
@@ -211,6 +215,12 @@ int hostapd_notif_assoc(struct hostapd_d
goto fail;
}
+ if (hostapd_ubus_handle_event(hapd, &req)) {
+ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
+ MAC2STR(req.addr));
+ goto fail;
+ }
+
#ifdef CONFIG_P2P
if (elems.p2p) {
wpabuf_free(sta->p2p_ie);
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -423,6 +423,7 @@ void ap_handle_timer(void *eloop_ctx, vo
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_INFO, "deauthenticated due to "
"local deauth request");
+ hostapd_ubus_notify(hapd, "local-deauth", sta->addr);
ap_free_sta(hapd, sta);
return;
}
@@ -578,6 +579,7 @@ skip_poll:
mlme_deauthenticate_indication(
hapd, sta,
WLAN_REASON_PREV_AUTH_NOT_VALID);
+ hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr);
ap_free_sta(hapd, sta);
break;
}
@@ -1294,6 +1296,7 @@ void ap_sta_set_authorized(struct hostap
buf, ip_addr, keyid_buf);
} else {
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
+ hostapd_ubus_notify(hapd, "disassoc", sta->addr);
if (hapd->msg_ctx_parent &&
hapd->msg_ctx_parent != hapd->msg_ctx)
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -259,6 +259,7 @@ static void hostapd_wpa_auth_psk_failure
struct hostapd_data *hapd = ctx;
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR,
MAC2STR(addr));
+ hostapd_ubus_notify(hapd, "key-mismatch", addr);
}
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -190,6 +190,12 @@ ifdef CONFIG_EAPOL_TEST
CFLAGS += -Werror -DEAPOL_TEST
endif
+ifdef CONFIG_UBUS
+CFLAGS += -DUBUS_SUPPORT
+OBJS += ubus.o
+LIBS += -lubox -lubus
+endif
+
ifdef CONFIG_CODE_COVERAGE
CFLAGS += -O0 -fprofile-arcs -ftest-coverage
LIBS += -lgcov
@@ -956,6 +962,9 @@ ifdef CONFIG_CTRL_IFACE_MIB
CFLAGS += -DCONFIG_CTRL_IFACE_MIB
endif
OBJS += ../src/ap/ctrl_iface_ap.o
+ifdef CONFIG_UBUS
+OBJS += ../src/ap/ubus.o
+endif
endif
CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -6794,6 +6794,8 @@ struct wpa_supplicant * wpa_supplicant_a
}
#endif /* CONFIG_P2P */
+ wpas_ubus_add_bss(wpa_s);
+
return wpa_s;
}
@@ -6820,6 +6822,8 @@ int wpa_supplicant_remove_iface(struct w
struct wpa_supplicant *parent = wpa_s->parent;
#endif /* CONFIG_MESH */
+ wpas_ubus_free_bss(wpa_s);
+
/* Remove interface from the global list of interfaces */
prev = global->ifaces;
if (prev == wpa_s) {
@@ -7123,8 +7127,12 @@ int wpa_supplicant_run(struct wpa_global
eloop_register_signal_terminate(wpa_supplicant_terminate, global);
eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
+ wpas_ubus_add(global);
+
eloop_run();
+ wpas_ubus_free(global);
+
return 0;
}
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -17,6 +17,7 @@
#include "wps/wps_defs.h"
#include "config_ssid.h"
#include "wmm_ac.h"
+#include "ubus.h"
extern const char *const wpa_supplicant_version;
extern const char *const wpa_supplicant_license;
@@ -310,6 +311,8 @@ struct wpa_global {
#endif /* CONFIG_WIFI_DISPLAY */
struct psk_list_entry *add_psk; /* From group formation */
+
+ struct ubus_object ubus_global;
};
@@ -520,6 +523,7 @@ struct wpa_supplicant {
unsigned char own_addr[ETH_ALEN];
unsigned char perm_addr[ETH_ALEN];
char ifname[100];
+ struct wpas_ubus_bss ubus;
#ifdef CONFIG_MATCH_IFACE
int matched;
#endif /* CONFIG_MATCH_IFACE */
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -33,6 +33,7 @@
#include "p2p/p2p.h"
#include "p2p_supplicant.h"
#include "wps_supplicant.h"
+#include "ubus.h"
#ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
@@ -392,6 +393,8 @@ static int wpa_supplicant_wps_cred(void
wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
cred->cred_attr, cred->cred_attr_len);
+ wpas_ubus_notify(wpa_s, cred);
+
if (wpa_s->conf->wps_cred_processing == 1)
return 0;
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -896,6 +896,7 @@ int main(int argc, char *argv[])
}
hostapd_global_ctrl_iface_init(&interfaces);
+ hostapd_ubus_add(&interfaces);
if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
wpa_printf(MSG_ERROR, "Failed to start eloop");
@@ -905,6 +906,7 @@ int main(int argc, char *argv[])
ret = 0;
out:
+ hostapd_ubus_free(&interfaces);
hostapd_global_ctrl_iface_deinit(&interfaces);
/* Deinitialize all interfaces */
for (i = 0; i < interfaces.count; i++) {
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -203,7 +203,7 @@ int main(int argc, char *argv[])
for (;;) {
c = getopt(argc, argv,
- "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W");
+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:nNo:O:p:P:qsTtuv::W");
if (c < 0)
break;
switch (c) {
@@ -271,6 +271,9 @@ int main(int argc, char *argv[])
params.conf_p2p_dev = optarg;
break;
#endif /* CONFIG_P2P */
+ case 'n':
+ iface_count = 0;
+ break;
case 'o':
params.override_driver = optarg;
break;
--- a/src/ap/rrm.c
+++ b/src/ap/rrm.c
@@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report
return;
wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s",
MAC2STR(addr), token, rep_mode, report);
+ if (len < sizeof(struct rrm_measurement_beacon_report))
+ return;
+ hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len);
}
@@ -350,6 +353,9 @@ void hostapd_handle_radio_measurement(st
mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa));
switch (mgmt->u.action.u.rrm.action) {
+ case WLAN_RRM_LINK_MEASUREMENT_REPORT:
+ hostapd_ubus_handle_link_measurement(hapd, buf, len);
+ break;
case WLAN_RRM_RADIO_MEASUREMENT_REPORT:
hostapd_handle_radio_msmt_report(hapd, buf, len);
break;
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -461,7 +461,7 @@ static void ieee802_11_rx_bss_trans_mgmt
size_t len)
{
u8 dialog_token, status_code, bss_termination_delay;
- const u8 *pos, *end;
+ const u8 *pos, *end, *target_bssid;
int enabled = hapd->conf->bss_transition;
struct sta_info *sta;
@@ -508,6 +508,7 @@ static void ieee802_11_rx_bss_trans_mgmt
wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field");
return;
}
+ target_bssid = pos;
sta->agreed_to_steer = 1;
eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta);
eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer,
@@ -527,6 +528,11 @@ static void ieee802_11_rx_bss_trans_mgmt
MAC2STR(addr), status_code, bss_termination_delay);
+ target_bssid = NULL;
}
+ hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token,
+ status_code, bss_termination_delay,
+ target_bssid, pos, end - pos);
+
wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries",
pos, end - pos);
}