From a2672d1b42ca061c43fa450e3d1dddc8be60d435 Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Wed, 13 Dec 2023 10:38:47 +0530 Subject: [PATCH] hostapd: fix forming the NL commands with single drv With Single Drv changes, now drv structure is not tightly coupled with a radio. Currently, many NL commands assume that and hence sends the command on drv->first_bss or drv->ifindex which could not be the intended BSS. As a result of this the command is rejected in kernel. Hence, to fix this issue, use the passed BSS or bss->ifindex to form the message in order to ensure it is sent for the correct radio. Signed-off-by: Aditya Kumar Singh --- src/drivers/driver_nl80211.c | 40 +++++++++++++++---------------- src/drivers/driver_nl80211_scan.c | 16 +++++++------ 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index f53c6f547c65..cb161efa5214 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1824,7 +1824,7 @@ static int nl80211_channel_info(void *priv, struct wpa_channel_info *ci) struct wpa_driver_nl80211_data *drv = bss->drv; struct nl_msg *msg; - msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_INTERFACE); + msg = nl80211_bss_msg(bss, 0, NL80211_CMD_GET_INTERFACE); return send_and_recv_msgs(drv, msg, get_channel_info, ci, NULL, NULL); } @@ -4452,7 +4452,7 @@ static int wpa_driver_nl80211_set_acl(void *priv, nla_total_size(acl_nla_sz); nlmsg_sz = nlmsg_total_size(nla_sz); if (!(msg = nl80211_ifindex_msg_build(drv, nlmsg_alloc_size(nlmsg_sz), - drv->ifindex, 0, + bss->ifindex, 0, NL80211_CMD_SET_MAC_ACL)) || nla_put_u32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ? NL80211_ACL_POLICY_DENY_UNLESS_LISTED : @@ -7390,16 +7390,16 @@ fail: } -static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv, - int ifindex, enum nl80211_iftype mode) +static int nl80211_set_mode(struct i802_bss *bss, enum nl80211_iftype mode) { + struct wpa_driver_nl80211_data *drv = bss->drv; struct nl_msg *msg; - int ret = -ENOBUFS; + int ret = -ENOBUFS, ifindex = bss->ifindex; wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)", ifindex, mode, nl80211_iftype_str(mode)); - msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE); + msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_SET_INTERFACE); if (!msg || nla_put_u32(msg, NL80211_ATTR_IFTYPE, mode)) goto fail; @@ -7430,7 +7430,7 @@ static int wpa_driver_nl80211_set_mode_impl( if (TEST_FAIL()) return -1; - mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode); + mode_switch_res = nl80211_set_mode(bss, nlmode); if (mode_switch_res && nlmode == nl80211_get_ifmode(bss)) mode_switch_res = 0; @@ -7494,7 +7494,7 @@ static int wpa_driver_nl80211_set_mode_impl( } /* Try to set the mode again while the interface is down */ - mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode); + mode_switch_res = nl80211_set_mode(bss, nlmode); if (mode_switch_res == -EBUSY) { wpa_printf(MSG_DEBUG, "nl80211: Delaying mode set while interface going down"); @@ -7758,7 +7758,7 @@ static int i802_set_rts(void *priv, int rts) else val = rts; - if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) || + if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_WIPHY)) || nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) { nlmsg_free(msg); return -ENOBUFS; @@ -7786,7 +7786,7 @@ static int i802_set_frag(void *priv, int frag) else val = frag; - if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) || + if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_WIPHY)) || nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val)) { nlmsg_free(msg); return -ENOBUFS; @@ -10345,7 +10345,7 @@ static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq, arg.acs_exclude_6ghz_non_psc = acs_exclude_6ghz_non_psc; dl_list_init(&arg.survey_results->survey_list); - msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY); + msg = nl80211_bss_msg(bss, NLM_F_DUMP, NL80211_CMD_GET_SURVEY); if (!msg) return -ENOBUFS; @@ -10543,7 +10543,7 @@ static int nl80211_start_radar_detection(void *priv, return -1; } - if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_RADAR_DETECT)) || + if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_RADAR_DETECT)) || nl80211_put_freq_params(msg, freq) < 0) { nlmsg_free(msg); return -1; @@ -11667,7 +11667,7 @@ static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set, wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map", qos_map_set, qos_map_set_len); - if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_QOS_MAP)) || + if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_QOS_MAP)) || nla_put(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set)) { nlmsg_free(msg); return -ENOBUFS; @@ -11899,7 +11899,7 @@ static int nl80211_add_sta_node(void *priv, const u8 *addr, u16 auth_alg) wpa_printf(MSG_DEBUG, "nl80211: Add STA node"); - if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) || + if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_VENDOR)) || nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE) || @@ -12632,7 +12632,7 @@ static int nl80211_set_band(void *priv, u32 band_mask) "nl80211: QCA_BAND_MASK = 0x%x, QCA_BAND_VALUE = %d", qca_band_mask, qca_band_value); - if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) || + if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_VENDOR)) || nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, QCA_NL80211_VENDOR_SUBCMD_SETBAND) || @@ -13388,11 +13388,11 @@ static int nl80211_set_secure_ranging_ctx(void *priv, if (!params->peer_addr || !params->own_addr) return -1; - wpa_dbg(drv->ctx, MSG_DEBUG, + wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Secure ranging context for " MACSTR, MAC2STR(params->peer_addr)); - msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + msg = nl80211_bss_msg(bss, 0, NL80211_CMD_VENDOR); if (!msg || nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, @@ -13785,10 +13785,10 @@ static int nl80211_send_external_auth_status(void *priv, (drv->capa.flags & WPA_DRIVER_FLAGS_SME)) return -1; - wpa_dbg(drv->ctx, MSG_DEBUG, + wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: External auth status: %u", params->status); - msg = nl80211_drv_msg(drv, 0, NL80211_CMD_EXTERNAL_AUTH); + msg = nl80211_bss_msg(bss, 0, NL80211_CMD_EXTERNAL_AUTH); if (!msg || nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, params->status) || (params->ssid && params->ssid_len && @@ -14184,7 +14184,7 @@ static int nl80211_set_scs(void *priv, struct scs_latency_params *scs_drv) struct nlattr *params; int ret; - msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + msg = nl80211_bss_msg(bss, 0, NL80211_CMD_VENDOR); if (!msg) return -EINVAL; diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c index 6ce93249b10b..1db9dccb2849 100644 --- a/src/drivers/driver_nl80211_scan.c +++ b/src/drivers/driver_nl80211_scan.c @@ -75,13 +75,14 @@ static int get_noise_for_scan_results(struct nl_msg *msg, void *arg) } -static int nl80211_get_noise_for_scan_results( - struct wpa_driver_nl80211_data *drv, struct nl80211_noise_info *info) +static int nl80211_get_noise_for_scan_results(struct i802_bss *bss, + struct nl80211_noise_info *info) { + struct wpa_driver_nl80211_data *drv = bss->drv; struct nl_msg *msg; os_memset(info, 0, sizeof(*info)); - msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY); + msg = nl80211_bss_msg(bss, NLM_F_DUMP, NL80211_CMD_GET_SURVEY); return send_and_recv_msgs(drv, msg, get_noise_for_scan_results, info, NULL, NULL); } @@ -997,8 +998,9 @@ static void nl80211_update_scan_res_noise(struct wpa_scan_res *res, static struct wpa_scan_results * -nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv) +nl80211_get_scan_results(struct i802_bss *bss) { + struct wpa_driver_nl80211_data *drv = bss->drv; struct nl_msg *msg; struct wpa_scan_results *res; int ret; @@ -1009,7 +1011,7 @@ try_again: res = os_zalloc(sizeof(*res)); if (res == NULL) return NULL; - if (!(msg = nl80211_cmd_msg(drv->first_bss, NLM_F_DUMP, + if (!(msg = nl80211_cmd_msg(bss, NLM_F_DUMP, NL80211_CMD_GET_SCAN))) { wpa_scan_results_free(res); return NULL; @@ -1035,7 +1037,7 @@ try_again: wpa_printf(MSG_DEBUG, "nl80211: Received scan results (%lu " "BSSes)", (unsigned long) res->num); - if (nl80211_get_noise_for_scan_results(drv, &info) == 0) { + if (nl80211_get_noise_for_scan_results(bss, &info) == 0) { size_t i; for (i = 0; i < res->num; ++i) @@ -1062,7 +1064,7 @@ struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv) struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_scan_results *res; - res = nl80211_get_scan_results(drv); + res = nl80211_get_scan_results(bss); if (res) wpa_driver_nl80211_check_bss_status(drv, res); return res; -- 2.17.1